[][src]Function tao_of_rust::ch05::lifetime::lifetime_params

pub fn lifetime_params()

生命周期参数

Base usage: 在无参数的时候,不能返回借用

fn return_str<'a>() -> &'a str {
    let mut s = "Rust".to_string();
    for i in 0..3 {
        s.push_str("Good ");
    }
    &s[..]                   //"Rust Good Good Good"
}
fn main() {
    let x = return_str();
}Run

Base usage: 函数的参数和返回值的引用必须相关联

fn foo<'a>(x: &'a str, y: &'a str) -> &'a str {
    let result = String::from("really long string");
    // error[E0597]: `result` does not live long enough
    // 上面的错误提示在Rust 2018 edtion下又有了更精准的描述:
    // error[E0515]: cannot return value referencing local variable `result`
    result.as_str()
}
fn main() {
    let x = "hello";
    let y = "rust";
    foo(x, y);
}Run

Base usage: 一个必须标准生命周期参数但是没有标准的例子

// missing lifetime specifier 编译器无法推导传入和返回的借用是否合法
fn the_longest(s1: &str, s2: &str) -> &str {
    if s1.len() > s2.len() { s1 } else { s2 }
}
fn main() {
    let s1 = String::from("Rust");
    let s1_r = &s1;
    {
        let s2 = String::from("C");
        let res = the_longest(s1_r, &s2);
       println!("{} is the longest", res);
   }
}Run

Base usage: 标准生命周期参数修改上面代码

fn the_longest<'a>(s1: &'a str, s2: &'a str) -> &'a str {
    if s1.len() > s2.len() { s1 } else { s2}
}
fn main() {
    let s1 = String::from("Rust");
    let s1_r = &s1;
    {
        let s2 = String::from("C");
        let res = the_longest(s1_r, &s2);
       println!("{} is the longest", res); // Rust is the longest
   }
}Run

Base usage: 结构体生命周期参数 这里的生命周期参数标记,实际上是和编译器约定了一个规则:结构体实例的生命周期应小于或等于任意一个成员的生命周期。

struct Foo<'a> {
    part: &'a str,
}
fn main() {
    let words = String::from("Sometimes think, the greatest sorrow than older");
    let first = words.split(',').next().expect("Could not find a ','");
    let f = Foo { part: first }; // 编译器在此处会根据约定的规则进行检查,看part的生命周期是否合法
    assert_eq!("Sometimes think", f.part);
}Run

Base usage: 为Foo<'a>结构体实现方法

#[derive(Debug)]
struct Foo<'a> {
    part: &'a str,
}
impl<'a> Foo<'a> {
    fn split_first(s: &'a str) -> &'a str {
         s.split(',').next().expect("Could not find a ','")
    }
    fn new(s: &'a str) -> Self {
       Foo {part: Foo::split_first(s)}
   }
   //满足 生命周期参数省略规则
   fn get_part(&self) -> &str {
       self.part
   }
}
fn main() {
    let words = String::from("Sometimes think, the greatest sorrow than older");
    println!("{:?}",Foo::new(words.as_str()));
}Run

Base usage: 省略生命周期参数

fn first_word(s: &str) -> &str {
    let bytes = s.as_bytes();
    for (i, &item) in bytes.iter().enumerate() {
        if item == b' ' {
            return &s[0..i];
        }
    }
    &s[..]
}
fn main() {
    println!("{:?}", first_word("hello Rust"));
}Run

Base usage: 省略生命周期参数示例

fn print(s: &str);                                           // 省略
fn print<'a>(s: &'a str);                                   // 展开
fn debug(lvl: uint, s: &str);                              // 省略
fn debug<'a>(lvl: uint, s: &'a str);                      // 展开
fn substr(s: &str, until: uint) -> &str;                 // 省略
fn substr<'a>(s: &'a str, until: uint) -> &'a str;     // 展开
fn get_str() -> &str;                                   // 非法
fn frob(s: &str, t: &str) -> &str;                    // 非法
fn get_mut(&mut self) -> &mut T;                           // 省略
fn get_mut<'a>(&'a mut self) -> &'a mut T;              // 展开
// 省略
fn args<T:ToCStr>(&mut self, args: &[T]) -> &mut Command
// 展开
fn args<'a, 'b, T:ToCStr>(&'a mut self, args: &'b [T]) -> &'a mut Command
fn new(buf: &mut [u8]) -> BufWriter;                      // 省略
fn new<'a>(buf: &'a mut [u8]) -> BufWriter<'a>          // 展开Run

Base usage: 生命周期限定

use std::fmt::Debug;
#[derive(Debug)]
struct Ref<'a, T: 'a>(&'a T);
fn print<T>(t: T)
where
    T: Debug,
{
    println!("`print`: t is {:?}", t);
}
fn print_ref<'a, T>(t: &'a T)
where
   T: Debug + 'a,
{
   println!("`print_ref`: t is {:?}", t);
}
fn main() {
   let x = 7;
   let ref_x = Ref(&x);
   print_ref(&ref_x);
   print(ref_x);
}Run

Base usage: 带生命周期参数的trait 对象

trait Foo {}
struct Bar<'a> {
    x: &'a i32,
}
impl<'a> Foo for Bar<'a> {}
fn main() {
    let num = 5;
    let box_bar = Box::new(Bar { x: &num });
    let obj = box_bar as Box<Foo>;
}Run

Base usage: 带生命周期参数的trait 对象,出错

trait Foo<'a> {}
struct FooImpl<'a> {
    s: &'a [u32],
}
impl<'a> Foo<'a> for FooImpl<'a> {
}
fn foo<'a>(s: &'a [u32]) -> Box<Foo<'a>> {
    Box::new(FooImpl { s: s })
}
fn main(){}Run

Base usage: 带生命周期参数的trait 对象,修正

trait Foo<'a> {}
struct FooImpl<'a> {
    s: &'a [u32],
}
impl<'a> Foo<'a> for FooImpl<'a> {
}
fn foo<'a>(s: &'a [u32]) -> Box<Foo<'a> + 'a> {
    Box::new(FooImpl { s: s })
}
fn main(){}Run