我有一个带有以下签名的函数:
pub fn history<'a, I: IntoIterator<Item = &'a str>>(&self, _: I)
稍后,我有一个名为main
的字段的结构,它是一个盒装闭包。
main: box |args: &[&str], shell: &mut Shell| {
shell.history.history(args);
},
重要的是我正在调用我用&[&str]
作为参数显示签名的函数。我得到以下编译错误:
src/main.rs:281:47: 281:54 error: type mismatch resolving `<&[&str] as core::iter::IntoIterator>::Item == &str`:
expected &-ptr,
found str [E0271]
src/main.rs:281 shell.history.history(args);
显然&[&str]
并不像IntoIterator
那样工作。我尝试shell.history.history(args.into_iter());
并收到类似的错误消息。
奇怪的是,shell.history.history(args.iter().map(|s|*s));
确实有效。这似乎不是正确的解决方案。
答案 0 :(得分:3)
我们来看看how IntoIterator
is implemented for slices:
impl<'a, T> IntoIterator for &'a [T]
type Item = &'a T
type IntoIter = Iter<'a, T>
fn into_iter(self) -> Iter<'a, T>
请注意,Item
被定义为T
的引用,其中T
是切片中项目的类型。由于您有一片&str
,这意味着Item
为&&str
。
您可以尝试使用.map(|s| *s)
取消引用外部引用并生成&str
的迭代器。
另一种解决方案是将history
函数概括为同时接受I: IntoIterator<Item = &'a str>
和I: IntoIterator<Item = &'b &'a str>
。为此,我们需要&'a str
和&'b &'a str
实现的特征。我们可以使用AsRef<str>
(感谢Vladimir Matveev指出这一点):
pub fn history<I: IntoIterator>(_: I)
where I::Item: AsRef<str>
{
for s in i {
println!("{}", s.as_ref());
}
}
fn main() {
history(&["s"]);
}