[][src]Function tao_of_rust::ch05::nll::borrow_ck_problem

pub fn borrow_ck_problem()

NLL: 非词法作用域生命周期

以下代码目前在 Rust 2015版本中 会出错,但是选择Rust 2018 edition将正常编译 可以去play.rust-lang.org选择2018 edtion版本尝试

Base usage: 案例1

struct Foo;

impl Foo {
    fn mutate_and_share(&mut self) -> &Self { &*self }
    fn share(&self) {}
}
let mut foo = Foo;
let loan = foo.mutate_and_share();
foo.share();Run

Base usage: 案例2

fn foo<'a>(x: &'a str, y: &'a str) -> &'a str {
    if x.len() % 2 == 0 {
        x
    } else {
        y
    }
}
fn main(){
    let x = String::from("hello");
    let z;
    let y = String::from("world");
    z = foo(&x, &y);
    println!("{:?}", z);
}Run

Base usage: 案例3

fn capitalize(data: &mut [char]) {
    // do something
}
fn bar() {
    let mut data = vec!['a', 'b', 'c'];
    let slice = &mut data[..]; // <-+ 'lifetime
    capitalize(slice);         //   |
    data.push('d'); // ERROR!  //   |
    data.push('e'); // ERROR!  //   |
    data.push('f'); // ERROR!  //   |
} // <------------------------------+Run

Base usage: 案例4,目前NLL解决不了的问题

fn get_default<'r,K:Hash+Eq+Copy,V:Default>(map: &'r mut HashMap<K,V>,
                                            key: K)
                                            -> &'r mut V {
    match map.get_mut(&key) { // -------------+ 'r
        Some(value) => value,              // |
        None => {                          // |
            map.insert(key, V::default()); // |
            //  ^~~~~~ ERROR               // |
            map.get_mut(&key).unwrap()     // |
        }                                  // |
    }                                      // |
}                                          // vRun

Base usage: 案例4修正

fn get_default2<'r,K:Hash+Eq+Copy,V:Default>(map: &'r mut HashMap<K,V>,
                                             key: K)
                                             -> &'r mut V {
    if map.contains_key(&key) {
    // ^~~~~~~~~~~~~~~~~~ 'n
        return match map.get_mut(&key) { // + 'r
            Some(value) => value,        // |
            None => unreachable!()       // |
        };                               // v
    }

    // At this point, `map.get_mut` was never
    // called! (As opposed to having been called,
    // but its result no longer being in use.)
    map.insert(key, V::default()); // OK now.
    map.get_mut(&key).unwrap()
}Run

Base usage: 案例5 无限循环

struct List<T> {
    value: T,
    next: Option<Box<List<T>>>,
}

fn to_refs<T>(mut list: &mut List<T>) -> Vec<&mut T> {
    let mut result = vec![];
    loop {
        result.push(&mut list.value);
        if let Some(n) = list.next.as_mut() {
            list = n;
        } else {
            return result;
        }
    }
}Run

Base usage: 案例6, NLL目前还未解决

fn main() {
    let mut x = vec![1];
    x.push(x.pop().unwrap());
}Run