Reference 生命周期';从作为参数传递给函数的引用返回内部引用时的处理

Reference 生命周期';从作为参数传递给函数的引用返回内部引用时的处理,reference,rust,lifetime,mutable,Reference,Rust,Lifetime,Mutable,尽管生命周期'a和'b彼此独立,但以下代码编译良好的原因是什么 struct Foo<'a> { i: &'a i32 } fn func<'a, 'b>(x: &'a Foo<'b>) -> &'b i32 { x.i } fn main() {} fn func<'a, 'b>(x: &'a Foo<'b>) -> &'b i32 { x.i } 产

尽管生命周期
'a
'b
彼此独立,但以下代码编译良好的原因是什么

struct Foo<'a> {
    i: &'a i32
}

fn func<'a, 'b>(x: &'a Foo<'b>) -> &'b i32 {
    x.i
}

fn main() {}
fn func<'a, 'b>(x: &'a Foo<'b>) -> &'b i32 {
    x.i
}
产生上述错误的原因是什么?。它是否认为它是对可变引用的所有权,并且它发现(从<代码> FoO < /代码>)被取出(具有独立的生命周期),这是不可能的,因此错误?

这个代码(我认为会通过)也失败了:

struct Foo<'a> {
    i: &'a mut i32
}

fn func<'a, 'b: 'a>(x: &'a Foo<'b>) -> &'b i32 {
    x.i
}

fn main() {}
struct Foo src/main.rs:6:5
|
5 | fn func
产生上述错误的原因是什么?。它认为它是
对可变引用的所有权,它可以看到某些东西(从
Foo
) 正在取出(具有独立的生命周期),而不是 是否可能,因此出现了错误

可变借阅确实不能移出Foo,因为可变借阅不是
Copy
。它隐式地不可变地重新箭头显示:

fn func <'a, 'b> (x:&'a Foo<'b>) -> &'b i32 {
    &*x.i
}
版本2(未能编译):

将版本3替换为版本4显示了在这种情况下仍然活动的外部不可变借用如何防止第二个可变借用。外部不可变借用上的生存期
'a
被新要求
'a:'b
强制扩展为等于生存期
'b

error[E0502]:无法将`*mutref_s`作为可变项借用,因为`*mutref_s`也作为不可变项借用
-->src/main.rs:20:5
|
17 |设ref_mutref_s=&mutref_s;
|-----此处发生不可变借用
...
20 | mutrefu.s.clear();
|^^^^^^^^^^此处发生可变借用
...
23 | }
|-不可变的借阅到此结束
尽管生命周期
'a
'b
彼此独立,但以下代码编译良好的原因是什么

struct Foo<'a> {
    i: &'a i32
}

fn func<'a, 'b>(x: &'a Foo<'b>) -> &'b i32 {
    x.i
}

fn main() {}
fn func<'a, 'b>(x: &'a Foo<'b>) -> &'b i32 {
    x.i
}
如果我使
Foo
中的引用
I
可变,它将给出以下错误

5 | fn func<'a, 'b>(x: &'a Foo<'b>) -> &'b i32 {
  |                    -----------     -------
  |                    |
  |                    this parameter and the return type are declared with different lifetimes...
6 |     x.i
  |     ^^^ ...but data from `x` is returned here
5 | fn func(x:&'a Foo只是为了添加一个建议(有关您问题的详细解释,请参阅其他答案):

只要有可能,不要过度设计寿命

在本例中,明确所有生命周期意味着4种情况(以及相当多的思考!)

案例1(编译)

fn func&'a i32{
x、 我
}

谢谢。如果版本2和版本3基本相同,那么为什么错误消息不同?对于版本3中的“数据流动”意味着什么?@soupybionics我不知道为什么它们不同,但是当您删除版本2上的返回值并分配给变量时,您也会得到“数据流动”具有相同错误代码的消息:生命周期错误消息并不总是完全正确。我在游乐场链接中包含了一个示例,其中
&'a&'b mut i32
分为一个片的vec和一个片,这应该清楚“数据流”的含义在哪里派生自。谢谢,这很有帮助!我试图理解什么样的语言机制规定“引用仍然是”通过“变量x”,我认为这里没有实际发生……我认为发生的是插入了一个“(
&*x.I
)(找不到任何文档),这就是。
fn func<'a, 'b>(x: &'a &'b mut i32) -> &'b i32 {
    x
}
fn func<'a, 'b: 'a>(x: &'a &'b mut i32) -> &'b i32 {
    x
}
fn func<'a: 'b, 'b>(x: &'a &'b mut i32) -> &'b i32 {
    x
}
fn func<'a, 'b: 'a>(x: &'a &'b mut String) -> &'b str {
    unsafe { std::mem::transmute(&**x as &str) } // force compilation
}

fn main() {
    let mut s = String::from("s");
    let mutref_s = &mut s;
    let ref_s = {
        let ref_mutref_s = &mutref_s;
        func(ref_mutref_s)
    };
    // use the mutable reference to invalidate the string slice       
    mutref_s.clear();
    mutref_s.shrink_to_fit();
    // use the invalidated string slice
    println!("{:?}", ref_s);
}
fn func<'a, 'b>(x: &'a Foo<'b>) -> &'b i32 {
    x.i
}
fn func<'a, 'b: 'a>(x: &'a Foo<'b>) -> &'b i32 {
    x.i
}
fn func<'a, 'b: 'a>(x: &'a Foo<'b>) -> &'a i32 {
    x.i
}
fn func<'a: 'b, 'b>(x: &'a Foo<'b>) -> &'a i32 {
    x.i
}
fn func<'a: 'b, 'b>(x: &'a Foo<'b>) -> &'b i32 {
    x.i
}
fn func<'a, 'b: 'a>(x: &'a Foo<'b>) -> &'b i32 {
    x.i
}
fn func<'a>(x: &'a Foo) -> &'a i32 {
    x.i
}