为什么编译器在将切片视为迭代器时期望双重引用而不是引用?

Why does the compiler expect a double reference instead of a reference when treating a slice as an iterator?

我想创建一个接受 Vec<String>&[&str] (以及其他类型)的结构:

pub struct Channel<I, T>
where
    I: IntoIterator<Item = T>,
    T: AsRef<str>,
{
    pub name: String,
    pub instruments: I,
}

传递 Vec<String> 时,它按预期工作:

pub struct Response {
    pub channels: Channel<Vec<String>, String>,
}

但是当传递一个 &[&str]:

pub struct Request<'a> {
    pub channels: Channel<&'a [&'a str], &'a str>,
}

...我收到以下错误:

error[E0271]: type mismatch resolving `<&'a [&'a str] as IntoIterator>::Item == &'a str`
  --> src/lib.rs:11:19
   |
11 |     pub channels: Channel<&'a [&'a str], &'a str>,
   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `str`, found `&str`
   |
   = note: expected reference `&'a str`
              found reference `&&'a str`
note: required by a bound in `Channel`
  --> src/lib.rs:3:21
   |
1  | pub struct Channel<I, T>
   |            ------- required by a bound in this
2  | where
3  |     I: IntoIterator<Item = T>,
   |                     ^^^^^^^^ required by this bound in `Channel`

为什么在那种情况下 T 被视为 &&'a str

解决方案是改用下面的表示法,但我真的很想知道为什么将 T 写成 &'a str,实际上是这样,但行不通。

pub struct Request<'a> {
    pub channels: Channel<&'a [&'a str], &'a &'a str>,
}

IntoIterator 对于 &[T] 产生引用:&T,因此由于您的切片类型是 &str,迭代器 Item&&str .

此外,您的代码可以通过不接受第二个泛型参数来简化。您可以使用 I::Item 来约束迭代器类型:

pub struct Channel<I>
where
    I: IntoIterator,
    I::Item: AsRef<str>,
{
    pub name: String,
    pub instruments: I,
}

let channels: Channel<Vec<String>>;
let channels: Channel<&[&str]>;