Editor's note: The code in this question predates Rust 1.0. Since then, semantics have changed and some of the assertions made in the question are no longer true.
I have the following piece of code:
extern crate debug;
use std::mem::size_of_val;
struct A<'a> {
a: &'a [i64],
}
fn main() {
// code
}
When I define a slice with &
(i.e. &[1, 2, 3]
) as in the following println!
println!("{} - {:?}", size_of_val(&A { a: &[1, 2, 3] }), A { a: &[1, 2, 3] });
the output is
16 - A<'static>{a: &[1i64, 2i64, 3i64]}
Defining a slice without &
println!("{} - {:?}", size_of_val(&A { a: [1, 2, 3] }), A { a: [1, 2, 3] });
gives me the same result
16 - A<'static>{a: &[1i64, 2i64, 3i64]}
If I first try to bind an instance of a struct A
, whose a
field is initialized with a reference to a slice (i.e. using &
), to a variable x
let x = A { a: &[1, 2, 3] }; // &[1, 2, 3] is a reference to a slice
and I try to execute a similar println!
as the previous ones
println!("{} - {:?}", size_of_val(&x), x);
I get
16 - A<'static>{a: &[1i64, 2i64, 3i64]}
However, if I bind an instance of A
, whose a
field is initialized to a slice (not a reference to a slice using &
), to a variable x
let x = A { a: [1, 2, 3] };
and I try to execute a similar println!
as the previous ones
println!("{} - {:?}", size_of_val(&x), x);
I get the following build error:
/prpath/main.rs:12:20: 12:29 error: borrowed value does not live long enough /prpath/main.rs:12 let x = A { a: [1 ,2, 3] }; ^~~~~~~~~ /prpath/main.rs:11:11: 15:2 note: reference must be valid for the block at 11:10... /prpath/main.rs:11 fn main() { /prpath/main.rs:12 let x = A { a: [1 ,2, 3] }; /prpath/main.rs:13 /prpath/main.rs:14 println!("{} - `{:?}`", size_of_val(&x), x); /prpath/main.rs:15 } /prpath/main.rs:12:5: 12:31 note: ...but borrowed value is only valid for the statement at 12:4; consider using a `let` binding to increase its lifetime /prpath/main.rs:12 let x = A { a: [1 ,2, 3] }; ^~~~~~~~~~~~~~~~~~~~~~~~~~ error: aborting due to previous error
I was expecting that only the A { a: &[1, 2, 3] }
definition was allowed because A.a
should have &[i64]
type, but, apparently, Rust allows us to not include an &
symbol.
What is the difference between A { a: &[1, 2, 3] }
and A { a: [1, 2, 3] }
? Why are we allowed to use A { a: [1, 2, 3] }
(in the second example above)?