5 ms·
Length=capacity is already available, and always has been, as Box<[T]>
by unanswered 6y ago
Length=capacity is already available, and always has been, as Box<[T]>
- brundolf 6y agoCan [T] be any length, decided at runtime?
- unanswered 6y agoYes.
- brundolf 6y agoThat's news to me, and good to know. Seems moldavi's original comment was incorrect
- unanswered 6y agoMost of what you read online is, especially about rust.
- steveklabnik 6y agoI mean, it depends on the words you use. "Array" has a specific meaning in Rust, and that's [T; N]. You cannot have a run-time value for N, and so in that sense, they are correct. If by "array" you mean "any number of values laid out next to each other in memory," then they're wrong, but that's not usually what this term means in Rust specifically. Vectors and slices are also laid out this way, but they're not called "arrays." 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.
- brundolf 6y agoSo 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.