News for hackers. Stuff that matters.
Re:Grids in Rust, Part 2: const generics by brundolf on Monday April 05, 2021 @01:16PM (#26701748)
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])

Re:Grids in Rust, Part 2: const generics by steveklabnik on Monday April 05, 2021 @02:36PM (#26702790)
You 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.

Re:Grids in Rust, Part 2: const generics by brundolf on Monday April 05, 2021 @03:12PM (#26703284)
I 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.
Re:Grids in Rust, Part 2: const generics by steveklabnik on Monday April 05, 2021 @03:20PM (#26703361)
Totally. 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.