Skip to content

泛型, trait和生命周期

泛型

1
2
3
fn largest<T>(list: &[T]) -> T {
    return list[0];
}

trait

类似于其他语言的接口概念

定义:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
pub struct A {
    pub class_name1:String,
}

pub struct B {
    pub class_name2:String,
}

// define trait
pub trait Trait {
    fn do1(&self) -> String;
    fn do_default(&self) -> String {
        self.do1()
    }
}

// implement trait
impl Trait for A {
    fn do1(&self) -> String {
        self.class_name1.clone()
    }
}

使用

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// use trait
pub fn execute(class: impl Trait){
    class.do_default();
}

// 泛型
pub fn execute2<T: Trait>(item1: T, item2: T) {
}

// multi bound
pub fn execute3(class: impl Trait+Clone){
    class.do_default();
}

// where
fn execute4<T, U>(t: T, u: U)
    where T: Trait + Clone,
          U: Clone + Trait
{}

// return
pub fn execute5()->Box<dyn Trait>{
    return Box::new(A{class_name1:"AAAA".to_string()});
}

重载运算符:

1
2
3
fn largest<T: PartialOrd + Copy>(list: &[T]) -> T {
    return list[0]
}

生命周期

下面代码报错, rust无法自动推导检查返回值的生命周期:

1
2
3
4
// expected named lifetime parameter
fn longest(a: &str, b: &str)->&str{
    a
}

修正, 用'a 标注被应用的参数, 注明生命周期, 这里指让编译器检查 x,y是否和返回值有一样长的生命周期:

1
2
3
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
    x
}

因为生命周期, 函数内部定义的引用不能传递到外面:

1
2
3
4
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
    let c=String::from("Acc");
    return c.as_str(); // returns a value referencing data owned by the current function
}

这里直接返回String, 把控制权交给调用者即可:

1
2
3
4
fn longest<'a>(x: &'a str, y: &'a str) -> String {
    let c=String::from("Acc");
    c
}

生命周期省略:

  • 函数除去&self, 仅有一个参数;
  • 或者函数有&self, 使用self周期作为返回值周期.

静态生命周期 'static: 持续整个程序时间