How does comparison of a slice with an array work

2019-07-27 01:19发布

Why would [1,1] == &[1,1] not even compile (presumably because they're different types), yet the following snippet compiles and runs fine.

let a: [i32; 100] = [1; 100];
let b: &[i32] = &a[1..3];
if b == [1, 1] { // comparison with &[1, 1] works as well
    println!("it works"); // this does get printed
}

1条回答
Root(大扎)
2楼-- · 2019-07-27 01:55

Right now, arrays in Rust are somewhat special because Rust lacks type-level integers. You can't write a function fn f<T, N>(array: &[T; N]). Likewise, you can't implement a trait which is generic over N.

The standard library provides some trait implementations for array lengths ranging from 0 to 32 to mitigate this issue, which is why b == [1,1] works. There's an implementation of the trait PartialEq for this case:

impl<'a, 'b, A, B> PartialEq<[A; 2]> for &'b [B] 
where B: PartialEq<A>

However, the trait PartialEq<&[A; 2]> is not implemented for [B; 2]. Thus you cannot compare [1, 1] and &[1, 1]. b == [1; 33] will not work in your example too, as there's no implementations for arrays longer than 32 elements.

But there's ongoing effort to bring type-level integers into Rust. RFC 2000 is the latest proposal.

For the time being you can rely on implicit conversion from reference to the array to reference to slice. Like this

fn f<T>(slice: &[T]) {}

f(&[1, 2, 3, 4]);
查看更多
登录 后发表回答