当前函数拥有的值引用数据

Value referencing data owned by the current function

这是我的代码:

struct Something<'a> {
    val: u32,
    another: &'a AnotherThing,
}

struct AnotherThing {
    val: u32,
}

impl Default for AnotherThing {
    fn default() -> Self {
        Self {
            val: 2,
        }
    }
}

trait Anything {
    fn new(val: u32) -> Self;
}

impl Anything for Something<'_> {
    fn new(val: u32) -> Self {
        Self {
            val,
            another: &AnotherThing::default(),
        }
    }
}

fn main() {
    let _ = Something::new(1);
}

无法编译因为:

   Compiling playground v0.0.1 (/playground)
error[E0515]: cannot return value referencing temporary value
  --> src/main.rs:24:9
   |
24 | /         Self {
25 | |             val,
26 | |             another: &AnotherThing::default(),
   | |                       ----------------------- temporary value created here
27 | |         }
   | |_________^ returns a value referencing data owned by the current function

我了解问题,但不知道如何解决。如果在这种情况下无法使用 Default 特征,我该如何处理函数所有权。下面是一个更简单的例子:

struct Something<'a> {
    val: u32,
    another: &'a AnotherThing,
}

struct AnotherThing {
    val: u32,
}

trait Anything {
    fn new(val: u32) -> Self;
}

impl Anything for Something<'_> {
    fn new(val: u32) -> Self {
        let at = AnotherThing { val : 2 };
        Self {
            val,
            another: &at,
        }
    }
}

fn main() {
    let _ = Something::new(1);
}

如果我有 another: &AnotherThing { val : 2 } 而不是 another: &at 就可以了。如果我想让 another 属性成为引用并从函数中获取值,我该怎么做?

你可以这样做

#[derive(Default)]
struct Something<'a> {
    val: u32,
    another: &'a AnotherThing,
}

struct AnotherThing {
    val: u32,
}

impl<'a> Default for &'a AnotherThing {
    fn default() -> &'a AnotherThing {
        &AnotherThing {
            val: 3,
        }
    }
}

trait Anything {
    fn new(val: u32) -> Self;
}

impl Anything for Something<'_> {
    fn new(val: u32) -> Self {
        Self {
            val,
            ..Default::default()
        }
    }
}

另一种选择是创建一个 const 项目,您可以创建一个具有 'static 生命周期的引用,从而绑定到任何 'a:

struct Something<'a> {
    val: u32,
    another: &'a AnotherThing,
}

struct AnotherThing {
    val: u32,
}

const ANOTHER_THING_DEFAULT: AnotherThing = AnotherThing { val: 3 };

trait Anything {
    fn new(val: u32) -> Self;
}

impl Anything for Something<'_> {
    fn new(val: u32) -> Self {
        Self {
            val,
            another: &ANOTHER_THING_DEFAULT,
        }
    }
}