Я хочу создать структуру, которая принимает как 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>,
}
На ваш вопрос могут ответить ответы В чем разница между iter и into_iter?; Разница между iter() и into_iter() в общем заимствованном Vec?. Если нет, пожалуйста, редактировать свой вопрос, чтобы объяснить различия. В противном случае мы можем пометить этот вопрос как уже отвеченный.
Посмотрите на реализацияIntoIterator
для &'a [T]
. Что такое T
в вашем коде?
IntoIterator
for &[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]>;
Как вы думаете, почему
&[T]
реализуетIterator<Item = T>
? (подсказка: это не так).