Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.5k views
in Technique[技术] by (71.8m points)

rust - What is the difference between a slice and an array?

Why are both &[u8] and &[u8; 3] ok in this example?

fn main() {
    let x: &[u8] = &[1u8, 2, 3];
    println!("{:?}", x);

    let y: &[u8; 3] = &[1u8, 2, 3];
    println!("{:?}", y);
}

The fact that &[T; n] can coerce to &[T] is the aspect that makes them tolerable. — Chris Morgan

Why can &[T; n] coerce to &[T]? In what other conditions does this coercion happen?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

[T; n] is an array of length n, represented as n adjacent T instances.

&[T; n] is purely a reference to that array, represented as a thin pointer to the data.

[T] is a slice, an unsized type; it can only be used through some form of indirection.

&[T], called a slice, is a sized type. It's a fat pointer, represented as a pointer to the first item and the length of the slice.

Arrays thus have their length known at compile time while slice lengths are a runtime matter. Arrays are second class citizens at present in Rust, as it is not possible to form array generics. There are manual implementations of the various traits for [T; 0], [T; 1], &c., typically up to 32; because of this limitation, slices are much more generally useful. The fact that &[T; n] can coerce to &[T] is the aspect that makes them tolerable.

There is an implementation of fmt::Debug for [T; 3] where T implements Debug, and another for &T where T implements fmt::Debug, and so as u8 implements Debug, &[u8; 3] also does.

Why can &[T; n] coerce to &[T]? In Rust, when does coercion happen?

It will coerce when it needs to and at no other times. I can think of two cases:

  1. where something expects a &[T] and you give it a &[T; n] it will coerce silently;
  2. when you call x.starts_with(…) on a [T; n] it will observe that there is no such method on [T; n], and so autoref comes into play and it tries &[T; n], which doesn’t help, and then coercion come into play and it tries &[T], which has a method called starts_with.

The snippet [1, 2, 3].starts_with(&[1, 2]) demonstrates both.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...