Box<[T]> is close, but it's a pointer + length, where the pointer is to the heap, whereas [T; N] is a series of values, and can be on the stack. That's why it's a "boxed slice" and not an "array."
And yes, any slice type is runtime sized. That's why slices exist; they have a length stored in them to keep track of how long they are. This goes for &[T], Box<[T]>, Arc<[T]>, any of them.
// returns a heap-allocated buffer of length new_arr_length
fn my_malloc<T>(new_arr_length: usize) -> Box<[T]> {
todo!()
}
The answer seems like no, looking at it, but it's possible there's a syntax for it I don't know aboutI guess what it comes down to is: slices can't own their data, can they (I'm genuinely not sure)? If so, and this is indeed a slice, then it should be impossible for this to work in this way
Though, in that case it would also seem fairly pointless (as opposed to a &[T])
// returns a heap-allocated buffer of length new_arr_length
fn my_malloc<T: Default + Clone>(new_arr_length: usize) -> Box<[T]> {
vec![T::default(); new_arr_length].into_boxed_slice()
}
> slices can't own their data, can they (I'm genuinely not sure)The problem is that "slice" can mean both &[T] and [T]. [T] is an unsized type, so it needs to be behind a pointer. Putting it behind a & is the common case, and doesn't have ownership because &T doesn't own T, but you can also put it behind Box<T>, which does have owership over T.
> Though, in that case it would also seem fairly pointless (as opposed to a &[T])
Yes, it's very niche. I've never used one in all my years of Rust. But Box<[T]> is two thirds of the size of Vec<T> (no need for capacity, since capacity == length) and maybe there are cases where that is significant, for example.
use std::sync::Arc;
fn foobar(s: &str) -> Arc<str> {
Arc::from(s.to_string())
}
You almost always can only create these sorts of values by casting.
I think the rest of these replies are presenting a false dichotomy; having a compile-time sized array doesn't change that.
Rust could easily have all three (compile-time-sized, runtime-sized, and Vec) but they chose not to. Probably because Vec is mostly good enough (albeit wasting a bit of memory).