What's the official name(noun) of [T]?


#1

Hi, i’m quite new to Rust. Today i was told (corrected) that the word “slice” actually refers to the type &[T] and not [T] itself. See the reference

Now i understand that [T] means a contiguous sequence of T(s),

but my question is, is there a name for [T]? What’s the proper official name (noun) for this type?


#2

It’s a slice, see the documentation for primitive.slice.

I think it’s fine to use slice as the nickname for [T], &[T] and &mut [T] and more, you can give each more specific names like “shared reference to slice” for &[T] or maybe “mutable slice” for &mut [T] or boxed slice for Box<[T]> if you need precision.

The doc apparently says

Slices are either mutable or shared. The shared slice type is &[T], while the mutable slice type is &mut [T], where T represents the element type.

Which is a grave simplification! The truth is more complicated, as you know, that the slice is a type in its own right, and can appear anywhere behind a pointer, including *const [T] or Box<[T]> or Arc<[T]> or insert your own contraption here!


#3

[T] is a dynamically sized type so when I need to be explicit I tend to say “dynamically sized slice.” The standard library documentation uses this as well: https://doc.rust-lang.org/std/#containers-and-collections

The standard library exposes three common ways to deal with contiguous regions of memory:

  • Vec<T> - A heap-allocated vector that is resizable at runtime.
  • [T; n] - An inline array with a fixed size at compile time.
  • [T] - A dynamically sized slice into any other kind of contiguous storage, whether heap-allocated or not.

Slices can only be handled through some kind of pointer, and as such come in many flavors such as:

  • &[T] - shared slice
  • &mut [T] - mutable slice
  • Box<[T]> - owned slice

#4

So [T] is under the name slice too.

Great, thanks.


#5

I think part of this confusion is historical. Once upon a time, Rust was a different language that did not a general mechanism for dynamically-sized types. [T] could not exist on its own. &[T] and &mut [T] were special cases in the language, called (mutable) slice. And there was probably a point where Box<[T]> did not exist (I don’t remember exactly).

Then DST came along and generalized things. SomeTrait (used as a type) and [T] are now both valid types of their own (though you can not have values of these types directly on the stack). Separately, &U, &mut U, Box<U>, and others are generalized so that they support any U, even dynamically sized. So &[T] is not a special case in the language anymore, it’s two concepts [T] and &U used together with U = [T].

I don’t know if it’s been done formally, but one way to retrofit the terminology for this new world is:

  • [T] is a slice.
  • &[T] is a shared reference to a slice, but is usually called a slice for short. It’s ambiguous, but [T] can rarely be used on its own anyway so context usually clarifies.
  • &mut [T] is a mutable reference to a slice (though I prefer to call &mut U exclusive reference), usually called mutable slice for short.
  • Box<[T]> is a boxed slice. (It’s rarely used in practice, since Vec<T> is more convenient and often works just as well.)