Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't I write a function with the same type as Box::new?

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).

like image 841
apt1002 Avatar asked Jan 05 '23 02:01

apt1002


1 Answers

[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.

like image 95
Simon Whitehead Avatar answered Jan 14 '23 00:01

Simon Whitehead