从具有自链接生存期的可变引用中获取不可变引用时有什么区别? [英] What are the differences when getting an immutable reference from a mutable reference with self-linked lifetimes?

查看:50
本文介绍了从具有自链接生存期的可变引用中获取不可变引用时有什么区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

struct Foo01<'a> {
    val: u32,
    str: &'a String,
}

fn mutate_and_share_01<'a>(foo: &'a mut Foo01<'a>) -> &'a Foo01<'a> {
    foo
}

fn mutate_and_share_02<'a>(foo: &'a mut Foo01<'a>) -> &'a Foo01 {
    foo
}

fn mutate_and_share_03<'a>(foo: &'a mut Foo01) -> &'a Foo01<'a> {
    foo
}

fn main() {
    let mut foo = Foo01 { val: 16, str: &String::from("Hello ") };
    let foo_mut = &mut foo;

    //let loan = mutate_and_share_01(foo_mut);
    //let loan2 = mutate_and_share_01(foo_mut); //error

    //let loan = mutate_and_share_02(foo_mut);
    //let loan2 = mutate_and_share_02(foo_mut); //error

    let loan = mutate_and_share_03(foo_mut);
    let loan2 = mutate_and_share_03(foo_mut); //good
}

这些 mutate_and_share 版本之间有什么区别?

What are differences between these mutate_and_share versions?

推荐答案

在情况1和2中,您说的是只要结构借用其参数,函数就借用该结构:

In cases 1 and 2, you're saying that the function borrows the structure for as long as the structure borrows its parameter:

foo:&'a mut Foo01<'a>

foo: &'a mut Foo01<'a>

这表示"foo是从'a'借来的,(&'a mut )和"foo借用'a "的参数"( Foo01<'a> ).

this says "foo is borrowed from 'a" (&'a mut) and "foo borrows its parameter for 'a" (Foo01<'a>).

就rustc而言,对该函数的调用将永远永远借用输入,因为该结构在其整个生命周期中都必然借用输入,因此您被锁定了:您不能借阅";通过删除输入内容,这样第二个呼叫将永远无法正常工作.

Meaning as far as rustc is concerned a call to this function will necessarily borrow the input forever, as the structure necessarily borrows its input for the entirety of its own lifetime, and thus you get locked out: you can't "unborrow" the input by dropping it so the second call can't work ever.

在情况3中,您将 output 的参数与内部借位相关联,这并不是真的,但至少在这种情况下效果很好.现实是这两个生命是不相关的:

In case 3 you're relating the parameter of the output to the internal borrow which isn't really true but works well enough at least for this case. The reality is that the two lifetimes are unrelated:

fn mutate_and_share<'a, 'b>(foo: &'a mut Foo01<'b>) -> &'a Foo01<'b> {
    foo
}

还请注意,您的第三种情况仅适用,因为您从未使用过 loan ,因此在第二行执行之前将其立即删除.如果您这样做:

Also do note that your third case only works because you're never using loan, so it's immediately dropped before the second line executes. If you do this:

    let loan = mutate_and_share_03(foo_mut);
    let loan2 = mutate_and_share_03(foo_mut); //good
    print("{}", loan.val)

然后,由于可变借项重叠,因此将不进行编译.

then it's not going to compile because the mutable borrows are overlapping.

哦,& String 通常是无用的.有& mut String 的用例,但是每当您看到对 String 的不可变引用时,最好使用& str .与& Vec< T> 相同,没有用,应为& [T] .

Oh, and &String is generally useless. There are use cases for &mut String, but any time you see an immutable reference to a String you'd be better off with an &str. Same with &Vec<T>, not useful, should be &[T].

这篇关于从具有自链接生存期的可变引用中获取不可变引用时有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆