If I write a function that takes one argument of type [f32]
(as opposed to e.g. &[f32]
), I get an error:
the trait bound `[f32]: std::marker::Sized` is not satisfied
The docs say this is because [f32]
does not have a compile-time-known size. A reasonable limitation. Fair enough.
However, there is at least one function in the standard library with this type. Here's me calling it:
let b: Box<[f32]> = Box::new([1.0, 2.0, 3.0]);
How come this is allowed in the standard library and not in my code? What is the relevant difference? (There's no obvious magic in the source).
[f32]
is unsized. However, [1.0, 2.0, 3.0]
is sized... its type is [f32; 3]
.
That's what T
will be when compiled with the standard library code, an [f32; 3]
sized array.
To accept a sized array yourself, you can do the same:
fn my_func(array: [f32; 3]) {
// Implementation here
}
my_func([1.0, 0.0, 0.0]);
Click here to see a working sample on the Playground
An &[f32]
slice is sized too.. which is why it is allowed also.
As Lukas points out in the comments, slices are a "fat pointer" (You can read about Dynamically Sized Types in the Nomicon). Slice fat pointers consist of a pointer to a piece of data and a value representing how big that data is.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With