3 ms·
So could I write something like this? // returns a heap-allocated buffer of length new_arr_length fn my_malloc<T>(new_arr_length: usize) -> Box<[T]> {
by brundolf 6y ago
So could I write something like this?
// 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 about
I 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])
- steveklabnik 6y agoYou can't, but not because of the slice stuff, but because you have to give it valid values. This works // 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.
- brundolf 6y agoI see! That makes sense now. Unsized types are one of the Rust concepts that I haven't gotten a good handle on yet, probably mainly because they don't come up very often in practice. The only other one I know of is str, and I'm not even sure how I'd go about using a plain str.
- steveklabnik 6y agoTotally. It works the same way: it's gotta be behind a pointer. Arc<str> would be a signature for a threadsafe interned string, 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.