-1

I'm a bit lost on the concept of slices in rust. I know that [T] is a contiguous block of elements of type T with a unknown size and we need a pointer to that data to access it. What I don't understand is if we run the following code:

let slice: [u8] = arr[1..3];

Is the compiler trying to access the first and second element from 'arr' and storing it in the stack, but it can't do that since it does not know the size, therefore we are forced to refer the first and second element from 'arr' using a pointer like this:

let slice: [u8] = &arr[1..3];

Secondly, I don't get what it means when the documentation says that slices are a view onto a contiguous block of memory

How is str (a slice type) a view onto a contiguous block of memory? Isn't &str (a reference to a slice) a view onto a contiguous block of memory?

I come from a C++ background so it is a bit odd seeing how string and slices work in rust

  • `str` is not a slice, `&str` is. `[u8,n]` is not a slice type, `&[u8]` is. Because they are views onto a contiguous block of memory. The first operation does not work because the semantics of `arr[1..3]` is not "give me a copy of the array" (it is only defined with a preceeding `&`, and then means"give me a view of the array"). – CoronA Jul 06 '23 at 11:54
  • Question doesn't quite match, but [this answer](https://stackoverflow.com/a/61151916/11423104) addresses everything you're asking about. – isaactfa Jul 06 '23 at 11:55
  • 1
    @CoronA `str` and `[u8]` are definitely slices, `&str` and `&[u8]` are not. They are references to slice. There is some confusion with the terminology in the documentation, but this is what the types are named. – Chayim Friedman Jul 06 '23 at 12:17
  • I don't understand your first question. Are you asking why we need a reference? You seem to understand that this is because slices have no size at compile-time. – Chayim Friedman Jul 06 '23 at 12:18
  • I wanted to know why the statement `let slice: [u8] = arr[1..3];` is wrong. What is this line of code trying to do. Is `arr` returning a copy of the elements from 1 to 2 in the array, however since size is omitted from this new `copy` we can't actually store it on the stack so we are forced to use a reference to `arr`. – Humble Penguin Jul 06 '23 at 12:24
  • It is pretty pointless to argue on the meaning of code that doesn't compile. Is that what the programmer intended to do? Perhaps (though I doubt they really thought it through). Is that what the compiler understands? No, because the compiler doesn't understand this code. It doesn't compile. – Chayim Friedman Jul 06 '23 at 12:26
  • I would like to know what it actually means and why it is wrong – Humble Penguin Jul 06 '23 at 12:32
  • 1
    It doesn't compile, that's what happens. – Chayim Friedman Jul 06 '23 at 12:32
  • I think I figured that part out sherlock... – Humble Penguin Jul 06 '23 at 12:34
  • Yes, but that is _all_ what happens. As I said, it is pointless to argue about the meaning of the code that _doesn't compile_. – Chayim Friedman Jul 06 '23 at 12:35
  • The reason that it doesn’t compile is because Rust can’t know how large the slice is, and because of this, doesn’t know how much space the variable `x` actually needs. The `&` creates a fat pointer to this slice, which is a pointer that also knows the length of the data it’s pointing to. What you wrote isn’t wrong in the sense that it’s syntactically invalid, but in the sense of “Rust can’t execute this”, because as I said earlier, it doesn’t know how much space on the stack `x` needs. – PatientPenguin Jul 06 '23 at 12:37
  • @PatientPenguin so when I run the following code `let slice: [u8] = arr[1..3];` is it creating a `sub array` and assigning that to slice, but since it can't figure out the size the code can't compile? Or is something else going on. – Humble Penguin Jul 06 '23 at 12:42
  • It can’t create an array, as an array has a fix size known at compile time. That line attempts to assign the unsized slice `arr[1..3]` to `slice`. In this case `arr[1..3]` is a view into `arr` with (from the compiler’s perspective) an unknown length. Only when you include the `&` do you have information about the length – PatientPenguin Jul 06 '23 at 12:50
  • By view, you mean it tries to return a copy of the elements or is it still referring to the original array? – Humble Penguin Jul 06 '23 at 12:54
  • 1
    It still refers to the original array. This link may help explain the confusion a bit: https://stackoverflow.com/questions/27879161/what-is-the-return-type-of-the-indexing-operation. Also, unrelated, but nice username ;) – PatientPenguin Jul 06 '23 at 14:12
  • You don't actually _need_ the `&` symbol, you can write `let ref slice = arr[1..3];` with the same semantics, but a more confusing syntax. – rodrigo Jul 06 '23 at 14:20

1 Answers1

1

Secondly, I don't get what it means when the documentation says that "slices are a view onto a contiguous block of memory"

You're right. The documentation is very confusing here. It is talking about references to slice, because slices themselves are not views, as we can prove by the existence of Box<[T]>. But while the technically accurate name for &[T] is "slice reference" (or "slice ref", "reference to slice"), the documentation uses the term "slice" to describe it in many places.

There is an open GitHub issue to fix the terminology here and in other places: #101353.

Chayim Friedman
  • 47,971
  • 5
  • 48
  • 77
  • [The reference](https://doc.rust-lang.org/reference/types/slice.html) refers to `&[T]`, `&mut [T]`, and `Box<[T]>` as "shared slice", "mutable slice", and "boxed slice" respectively, though as you mention those names don't show up in any official documentation that I know of. – isaactfa Jul 06 '23 at 14:24