Reputation: 42829
It is easy to create a boxed slice:
fn main() {
let _ = Box::new([42, 0]);
}
But if I want to add specify a type:
fn main() {
let _ = Box::<[i32]>::new([42, 0]);
}
I get:
error: no associated item named `new` found for type `std::boxed::Box<[i32]>` in the current scope
--> src/main.rs:2:13
|
2 | let _ = Box::<[i32]>::new([42, 0]);
| ^^^^^^^^^^^^^^^^^
|
= note: the method `new` exists but the following trait bounds were not satisfied: `[i32] : std::marker::Sized`
This is really strange, because it works with type ascription:
fn main() {
let _: Box<[i32]> = Box::new([42, 0]);
}
Upvotes: 1
Views: 3362
Reputation: 431619
It is easy to create a boxed slice
Except you didn't do that. If you print the type, you can see that Box::new([1, 2])
creates a boxed array, not a slice. On the other hand, let _: Box<[i32]> = Box::new([1, 2])
creates a boxed array and the converts it to a boxed slice. These have different types. Notably, the first type has a length known at compile time, the second no longer does.
You can use as
as well:
fn main() {
let _ = Box::new([1, 2]) as Box<[i32]>;
}
Box::<[i32]>::new([1, 2])
doesn't work for the reason the error message says: T
is not Sized
. T
is directly mapped to the type being boxed.
Box::new([1, 2]) as Box<[i32]>
works because a sized item is passed to Box::new
and then it is converted to a type with an unsized inner bit using unsized coercions.
It appears that unsized coercions don't apply for actual type ascription, an unstable feature in nightly Rust:
#![feature(type_ascription)]
fn main() {
let foo = Box::new([1, 2]): Box<[i32]>;
}
For this specific case, you can use into_boxed_slice
, which should avoid the need for any stack allocation.
vec![1, 2].into_boxed_slice();
Upvotes: 6
Reputation: 22273
This is an experimental feature:
#![feature(type_ascription)]
fn main() {
let _ = Box::new([42, 0]: [i32; 2]);
}
Also, in that case you need to be explicit about the length.
Upvotes: 2