美文网首页
rust 泛型

rust 泛型

作者: xiongzenghui | 来源:发表于2018-08-12 17:43 被阅读75次

    1、rust标准库#Option

    1. Option在rust标准库中的定义

    enum Option<T> {
        Some(T),
        None,
    }
    

    2. Option的典型用法

    fn main()
    {
      let x: Option<i32> = None;
      let y: Option<i32> = Some(5);
      let z: Option<f64> = Some(5.0f64);
    
      println!("{:?}", x);
      println!("{:?}", y);
      println!("{:?}", z);
    }
    
    ➜  main make
    rustc main.rs
    ./main
    None
    Some(5)
    Some(5.0)
    ➜  main
    

    3. match 解包 Option

    fn main()
    {
      let x: Option<i32> = None;
      let y: Option<i32> = Some(5);
      let z: Option<f64> = Some(5.0f64);
    
      match x {
        Some(x) => { println!("x = {}", x) },
        None => { println!("x = None") },
      }
    
      match y {
        Some(y) => { println!("y = {}", y) },
        None => { println!("y = None") },
      }
    
      match z {
        Some(z) => { println!("z = {:?}", z) },
        None => { println!("z = None") },
      }
    }
    
    ➜  main make
    rustc main.rs
    ./main
    x = None
    y = 5
    z = 5.0
    ➜  main
    

    4. if let 解包 Option

    fn main()
    {
      let x: Option<i32> = None;
      let y: Option<i32> = Some(5);
      let z: Option<f64> = Some(5.0f64);
    
      if let Some(val) = x {
        println!("val = {}", val);
      } else {
        println!("x = None");
      }
    
      if let Some(val) = y {
        println!("val = {}", val);
      } else {
        println!("y = None");
      }
    
      if let Some(val) = z {
        println!("val = {:?}", val);
      } else {
        println!("z = None");
      }
    }
    
    ➜  main make
    rustc main.rs
    ./main
    x = None
    val = 5
    val = 5.0
    ➜  main
    

    5. while let 解包 Option

    fn main()
    {
      // 可变绑定的可选值
      let mut num: Option<i32> = Some(0);
      
      // while let 解包/打包 Option类型的变量
      while let Some(i) = num {
        if i > 5 {
          num = None; // 可选值赋值为None
          break;
        } else {
          print!("{}, ", i); 
          num = Some(i+1); // 可选值+1后,继续打包为可选值
        }
      }
      println!(""); 
      println!("num = {:?}", num);
    }
    
    ➜  main make
    rustc main.rs
    ./main
    0, 1, 2, 3, 4, 5,
    num = None
    ➜  main
    

    2、类似于C++模板编程

    1. 函数模板

    fn make_pair<T, U>(a: T, b: U) -> (T, U) {
      (a, b)
    }
    
    fn main()
    {
      let couple1 = make_pair("man", "female");
      println!("couple1 = {:?}", couple1);
    
      let couple2 = make_pair(99i32, 109f64);
      println!("couple2 = {:?}", couple2);
    }
    
    ➜  main make
    rustc main.rs
    ./main
    couple1 = ("man", "female")
    couple2 = (99, 109.0)
    ➜  main
    

    2. 函数模板 + 面向接口

    // 接口1
    trait Man {
      fn name(&self) -> String;
    }
    
    // 接口2
    trait Animal {
      fn name(&self) -> String;
    }
    
    // 接口3
    trait Runnable {
      fn run(&self);
    }
    
    fn make_pair<T, U>(a: T, b: U) -> (T, U) 
      where T: Man, 
            U: Animal + Runnable // 模板参数U必须实现两个接口
    {
      (a, b)
    }
    
    fn main()
    {}
    

    3. 类(struct)模板

    #[derive(Debug)]
    struct Point<T> {
      x: T,
      y: T,
    }
    
    fn main()
    {
      let int_origin = Point { x: 0, y: 0 };
      let float_origin = Point { x: 0.0, y: 0.0 };
    
      println!("{:?}", int_origin);
      println!("{:?}", float_origin);
    }
    
    ➜  main make
    rustc main.rs
    ./main
    Point { x: 0, y: 0 }
    Point { x: 0.0, y: 0.0 }
    ➜  main
    

    3、type 关联模板参数类型

    1. 接口具体实现

    // 接口
    trait Graph {
      type N; // 模板参数1
      type E; // 模板参数2
    
      fn has_edge(&self, &Self::N, &Self::N) -> bool; // 返回bool
      fn edges(&self, &Self::N) -> &Vec<Self::E>; // 返回Vec数组的引用(临时使用权)
    }
    
    // 实体类
    struct Node;
    struct Edge;
    struct SimpleGraph {
      edges: Vec<Edge>
    }
    
    // 给实体类增加接口实现
    impl Graph for SimpleGraph {
      // 1. 给接口中模板参数,确定具体的数据类型
      type N = Node;
      type E = Edge;
    
      // 2. 接口方法实现1
      fn has_edge(&self, n1: &Node, n2: &Node) -> bool {
        return true;
      }
    
      // 3. 接口方法实现2
      fn edges(&self, n: &Node) -> &Vec<Edge> { //注意:-> Vec<E> 中的模板参数E要替换为具体数据类型
        return &(self.edges);
      }
    }
    
    fn main()
    {
      let graph = SimpleGraph {edges: vec![Edge{}, Edge{}, Edge{}]};
      let object = Box::new(graph) as Box<Graph<N=Node, E=Edge>>;
    }
    
    ➜  main make
    rustc main.rs
    ./main
    ➜  main
    

    2. < T > 绑定模板参数的接口作为函数参数类型

    // 接口定义
    trait Graph<N, E> {
      // 接口中方法定义时,函数形参不需要使用参数名
      fn has_edge(&self, &N, &N) -> bool;
      fn edges(&self, &N) -> Vec<E>;
    }
    
    // 全局函数,函数形参的类型为接口类型
    // => 必须先传入【N、E】的数据类型
    // => 再确定【Graph<N, E>】的数据类型
    fn distance<N, E, G: Graph<N, E>>(
      graph: &G, 
      start: &N, 
      end: &N) -> u32 {
      return 99;
    }
    
    fn main()
    {}
    

    3. type绑定模板参数的接口作为函数参数类型

    // 接口定义
    trait Graph {
      type N;
      type E;
    
      fn has_edge(&self, &Self::N, &Self::N) -> bool;
      fn edges(&self, &Self::N) -> Vec<Self::E>;
    }
    
    // 全局函数,函数形参的类型为接口类型
    fn distance<G: Graph>(
      graph: &G, 
      start: &G::N, 
      end: &G::N) -> i32 {
      return 99;
    }
    
    fn main()
    {}
    

    相关文章

      网友评论

          本文标题:rust 泛型

          本文链接:https://www.haomeiwen.com/subject/isasbftx.html