After reading the rust book many times I think I'm starting to get the gist of lifetimes, but for me, an additional problem is the syntax we need to use to declare them. I find it is really counterintuitive.
I've simplified a silly code of mine onto this pair of structs (which one referencing the other).
#[derive(Debug, Default)]
pub struct TestStructA {
pub byte_1: u8,
pub byte_2: u8,
pub vector: Vec<u8>,
}
impl<'a> Default for &'a TestStructA {
fn default() -> &'a TestStructA {
&TestStructA { byte_1: 10, byte_2: 20, vector: 'a vec![1, 2, 3] }
}
}
#[derive(Debug, Default)]
pub struct TestStructB<'a> {
pub test_array: &'a [u8],
pub t_a: &'a TestStructA,
}
If you copy and paste this isolated code onto a main.rs file and compile it, then you get the following error:
error: expected `while`, `for`, `loop` or `{` after a label
--> src/main.rs:10:59
|
10 | &TestStructA { byte_1: 10, byte_2: 20, vector: 'a vec![1, 2, 3] }
| ^^^ expected `while`, `for`, `loop` or `{` after a label
error: labeled expression must be followed by `:`
--> src/main.rs:10:59
|
10 | &TestStructA { byte_1: 10, byte_2: 20, vector: 'a vec![1, 2, 3] }
| ---^^^^^^^^^^^^^
| | |
| | help: add `:` after the label
| the label
|
= note: labels are used before loops and blocks, allowing e.g., `break 'label` to them
If I don't annotate the vector parameter lifetime, I get the expected: "check your lifetimes boy" (which makes sense).
error[E0515]: cannot return reference to temporary value
--> src/main.rs:10:9
|
10 | &TestStructA { byte_1: 10, byte_2: 20, vector: vec![1, 2, 3] }
| ^-------------------------------------------------------------
| ||
| |temporary value created here
| returns a reference to data owned by the current function
Of course, if I choose a more drastic solution as removing the "vector" attribute from my struct, as all other attributes are scalars, the code compiles. But I need my struct to have non-scalar data structures of some kind. I suspect I need some kind of lifetime labeling for my vector inside the Default initializer, but I'm not sure what
By the way, I think my TestStructB
is also properly lifetime annotated, but maybe not. Does it look correct?
Finally, I got here because the compiler said I needed to declare a Default initializer for the referenced (&) version of my original struct. This original struct was already happily used in my program, but never referenced. Whenever I started using it in a &referenced fashion, it was Rust claiming it needs its Default initializer. The thing is I still somewhat think I've done something wrong when using my referenced Struct, and that there is a proper way to use &referenced (and lifetime annotated) Structs without Rust complaining about their (non existing) default initializer.
EDIT: @JohnKugelman is more than right, I've come onto this "aberration" after the typical newbie fight with rust compiler trying to overcome the mainly cryptic messages it yields.
My simplified original was this one:
#[derive(Debug, Default)]
pub struct TestStructA {
pub byte_1: u8,
pub byte_2: u8,
pub vector: Vec<u8>,
}
#[derive(Debug, Default)]
pub struct TestStructB<'a> {
pub test_array: &'a [u8],
pub t_a: &'a TestStructA,
}
With this code, the error I get is:
error[E0277]: the trait bound `&TestStructA: Default` is not satisfied
--> src/main.rs:11:5
|
11 | pub t_a: &'a TestStructA,
| ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Default` is not implemented for `&TestStructA`
|
= help: the following implementations were found:
<TestStructA as Default>
= note: required by `std::default::Default::default`
= note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
Apparently rustc misled me into thinking I need a &Struct
Default initializer? Can't say...
impl<'a> Default for &'a TestStructA
-- what led you to this? Let's trace backwards and figure out why you think you need it, because it's awfully sketchy. I'm thinking you should delete this whole block and then ask us about the original error that led you here. – Unpolitictest_array: Vec<u8>, t_a: TestStructA
. – UnpoliticDefault
onTestStructB
? Can you just remove it? – Unpolitic