4 ms·
Yes, Rust lacks a runtime-sized array. I think the rest of these replies are presenting a false dichotomy; having a compile-time sized array doesn't change tha
by moldavi 6y ago
Yes, Rust lacks a runtime-sized array.
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).
- brundolf 6y agoA Vec is a length, capacity, and pointer. I don't see how you could implement Rust's safety guarantees with runtime-sized arrays that don't know their capacity (for bounds-checks). I guess you could theoretically do without the length/capacity distinction, so you could eliminate one value (but not two) by having "plain" runtime arrays. Overall I just can't imagine there are very many cases where eliminating a single number's worth of memory usage for an entire collection is worth having separate concepts with separate implementations, syntaxes, etc, not to mention all the downsides of not having reallocations/usage-length managed for you.
- unanswered 6y agoLength=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.