0

Here's my code:

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);
}

It doesn't compile because:

   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

I understand the problem but I don't know how to fix it. If it's not possible to use the Default trait for this case, how can I deal with the function ownership. Below a simpler example:

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);
}

If I had another: &AnotherThing { val : 2 } instead of another: &at it would work. If I want the another attribute to be a reference and get the value from a function, how can I do it?

E_net4
  • 27,810
  • 13
  • 101
  • 139
  • You cannot implement default for that structure. Instead you can make the "another" field optional -> `another: Option<&'a Another>`, then your default impl will just fill it with `None` – Svetlin Zarev Oct 04 '21 at 09:42
  • Does this answer your question? [Is there any way to return a reference to a variable created in a function?](https://stackoverflow.com/questions/32682876/is-there-any-way-to-return-a-reference-to-a-variable-created-in-a-function) – Svetlin Zarev Oct 04 '21 at 09:43
  • Many thanks for your help. I don't want the field to be optional. I could copy the `default()` code in the `new()` method and it would work. But I was wondering how I could implement the `another: &AnotherThing::default()` part. Even if it's not with the `Default` trait, but how the function can give ownership? I'll write another example. – user1238214 Oct 04 '21 at 10:14
  • I read your link, there was another link https://stackoverflow.com/questions/32300132/why-cant-i-store-a-value-and-a-reference-to-that-value-in-the-same-struct but I didn't get everything. – user1238214 Oct 04 '21 at 10:22

2 Answers2

0

You can do like this

#[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()
        }
    }
}
Zeppi
  • 1,175
  • 6
  • 11
0

Another option is to create a const item, of which you can create a reference with 'static lifetime, thus binding to any '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,
        }
    }
}
Filipe Rodrigues
  • 1,843
  • 2
  • 12
  • 21