1

I see slice has type [T], but when we take reference of an array, the returned slice is of type

&[i32; _]

i.e. per VSCode w/Rust Analyzer. However shouldn't it be of type

&[i32]

let arr:[i32;_] = [1,2];
let r_arr:&[i32;_] = &arr;

I am confused and it is not clear how to read &[i32;_] (apparently a Slice) vs &[i32;N] (an array), these two types definition seems ambiguous and very similar.

Rohit Sharma
  • 6,136
  • 3
  • 28
  • 47
  • Does this answer your question? [What is the difference between a slice and an array?](https://stackoverflow.com/questions/30794235/what-is-the-difference-between-a-slice-and-an-array) – AlphaModder Apr 25 '21 at 07:40
  • 1
    @AlphaModder apparently no, per rust analyzer, the slice is &[T;_], when it should be &[T] per your link/documentation – Rohit Sharma Apr 25 '21 at 07:43
  • When you take reference to an array, it is, well, literally reference to `[T; N]`. The confusion might be produced by the fact that `&[T; N]` can be automatically coerced to `&[T]` wherever it is necessary. – Cerberus Apr 25 '21 at 09:01

1 Answers1

1

&[i32;_] is a borrow of an array, while &[i32] is a slice, which means a dynamically sized array or a part of an array.

&[i32;_] means that the borrowed array has a statically known size _ which means the size is statically inferred (which must be 2 but not detailly shown by rust-analyzer), by the the item count of the given initializer [1, 2].

&[i32] means that it is a slice, which does not have a known size at compile time, and it is dynamically sized at runtime.

&[i32;_] is a thin pointer which means the actual memory layout of &[i32;_] is just a raw usize pointer to the starting position of the array.

&[i32] is a fat pointer which means the actual memory layout of &[i32] is made of 2 usizes. One is the raw pointer to the starting position of the slice, and the other one is the length of the slice.

Alsein
  • 4,268
  • 1
  • 15
  • 35
  • This is not what i understand from Tim - the author of Rust in Action and i quote ''' The [T] notation is not universal, but the ampersand (&) is significant. A string slice is created with &str and slices of arrays are &[T; N]''' https://twitter.com/timClicks/status/1386216326784450562. This whole concept is super confusing especially if there is implicit coercion going on as suggested by @cerberus – Rohit Sharma Apr 25 '21 at 10:11
  • @RohitSharma `[T]` is absolutely universal because it is a valid dynamic sized type. You can use a borrowed slice `&[T]`, as well as a boxed slice Box<[T]>, Rc<[T]> and anywhere else that could receive a DST, while `&`, as well as `&mut`, `*const` and `*mut` are fat pointers that could point to any DST such as [T], with an extra `usize` for the length (slices) or the virtual table(trait objects). – Alsein Apr 25 '21 at 10:59
  • As an aside @Alsein - can i ask where did you read "&[i32;_] means that the borrowed array has a statically known size _ which means the size is statically inferred", this is exactly the kind of info i am looking for (coming from haskell land i take _ as something to be ignored and does not have a different meaning) but some how the limited books i've read completely ignored it. If you can please suggest? – Rohit Sharma Apr 25 '21 at 11:20
  • 1
    It is not read, but inferred. The `_` for inference is not a valid syntax in rust stable, because currently rust only stabilized a basic usage of const generics. It is rust-analyzer's representation. Rust-analyzer uses `_` for inference because `_` for inference is available on type and lifetime generics. – Alsein Apr 25 '21 at 11:41