Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/rust/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Rust 为什么可以';我不能用`&;迭代器<;项目=&;字符串>;`作为迭代器?_Rust - Fatal编程技术网

Rust 为什么可以';我不能用`&;迭代器<;项目=&;字符串>;`作为迭代器?

Rust 为什么可以';我不能用`&;迭代器<;项目=&;字符串>;`作为迭代器?,rust,Rust,我有一个函数,它应该查找并返回给定迭代器的字符串的最长长度: fn max_width(strings: &Iterator<Item = &String>) -> usize { let mut max_width = 0; for string in strings { if string.len() > max_width { max_width = string.len();

我有一个函数,它应该查找并返回给定
迭代器的
字符串的最长长度:

fn max_width(strings: &Iterator<Item = &String>) -> usize {
    let mut max_width = 0;
    for string in strings {
        if string.len() > max_width {
            max_width = string.len();
        }
    }
    return max_width;
}
fn max_width<'a>(strings: impl Iterator<Item = &'a String>) -> usize
fn最大宽度(字符串:&迭代器)->usize{
设mut max_width=0;
对于字符串中的字符串{
if string.len()>最大宽度{
max_width=string.len();
}
}
返回最大宽度;
}
但是,编译器给了我以下错误:

error[E0277]:未满足特性绑定的'&std::iter::Iterator:std::iter::Iterator'
-->src/main.rs:3:19
|
3 |对于字符串中的字符串{
|^^^`&std::iter::Iterator`不是迭代器;可以尝试调用`.iter()`或类似的方法
|
=帮助:`&std::iter::Iterator`未实现特性'std::iter::Iterator'`
=注意:`std::iter::IntoIterator::into iter::所需`
我是个新手,对此感到非常困惑,因为我认为我是在显式地传递一个迭代器。调用
strings.iter()
告诉我它没有实现,调用
strings.into\u iter()
会让我陷入一个可变的兔子洞,我当然不想改变传递的参数


如何迭代字符串?

如果您不特别需要迭代任何给定迭代器的通用性,编写函数的一种更简单的方法是让您的
max_width
函数采用
&[&str]
(一段字符串片段)相反,您可以在
for
循环中使用切片,因为Rust知道如何将其转换为迭代器(它实现了
IntoIterator
特性):

您的代码失败,因为它与
&Iterator
不同。如果您将
迭代器
传递给函数,则可以修复此问题,但由于
迭代器
是一种特性,因此无法确定大小(您不知道传递的是什么
迭代器
)。解决方案是传递实现迭代器的任何内容:

fn max_width(strings: &Iterator<Item = &String>) -> usize {
    let mut max_width = 0;
    for string in strings {
        if string.len() > max_width {
            max_width = string.len();
        }
    }
    return max_width;
}
fn max_width<'a>(strings: impl Iterator<Item = &'a String>) -> usize
fn最大宽度)->使用


对于更有经验的用户:

最通用的方法可能是:

fn max_width<T: AsRef<str>>(strings: impl IntoIterator<Item = T>) -> usize {
    let mut max_width = 0;
    for string in strings {
        let string = string.as_ref();
        if string.len() > max_width {
            max_width = string.len();
        }
    }
    max_width
}
fn最大宽度(字符串:impl IntoIterator)->usize{
设mut max_width=0;
对于字符串中的字符串{
设string=string.as_ref();
if string.len()>最大宽度{
max_width=string.len();
}
}
最大宽度
}

但是,您也可以使用

fn max_width<T: AsRef<str>>(strings: impl IntoIterator<Item = T>) -> usize {
    strings
        .into_iter()
        .map(|s| s.as_ref().len())
        .max()
        .unwrap_or(0)
}
fn最大宽度(字符串:impl IntoIterator)->usize{
串
.into_iter()
.map(| s | s.as_ref().len())
.max()
.展开或(0)
}

其他答案向您展示了如何接受迭代器,但掩盖了对实际问题的回答:

为什么我不能使用
&Iterator
作为迭代器

有趣的是,你自己也阻止了它:

我当然不想改变已通过的论点

迭代器通过改变它们的目标来工作——这就是迭代器如何改变以为每个调用返回一个新值

pub trait Iterator {
    type Item;
    fn next(&mut self) -> Option<Self::Item>;
    //       ^^^
}
pub特征迭代器{
类型项目;
fn next(&mut self)->选项;
//       ^^^
}
通过接受一个不可变的trait对象,迭代器不可能更新自身,因此实际上不可能进行迭代

要使代码编译,您所能做的最简单的事情就是接受可变引用:

fn max_width(strings: &mut dyn Iterator<Item = &String>) -> usize
fn最大宽度(字符串:&mut-dyn迭代器)->usize
但是,我可能会将函数编写为:

fn max_width<I>(strings: I) -> usize
where
    I: IntoIterator,
    I::Item: AsRef<str>,
{
    strings
        .into_iter()
        .map(|s| s.as_ref().len())
        .max()
        .unwrap_or(0)
}
fn最大宽度(字符串:I)->使用
哪里
I:迭代器,
I::项目:AsRef,
{
串
.into_iter()
.map(| s | s.as_ref().len())
.max()
.展开或(0)
}
  • 不要使用显式的
    返回
  • 使用迭代器组合符,如和
  • 用于提供默认值
  • 用于接受可以生成迭代器的任何内容

  • 在函数末尾省略
    return
    是惯用的方法。只需写
    max\u width
    (不带分号)。谢谢,我会更新。Do
    &String
    的deref也是
    &str
    的,你不会通过吗?我想也许OP是Rust的新手,只是想迭代一堆字符串和一个Vec似乎是一种简单的方法。不过,通用解决方案很有趣。很抱歉,我应该添加我的用例!我正在解包fIELD从一个结构的向量(<代码> Max Sub(Cudiop.ItAudie).map(x x&x.NoX)),所以我已经有了一个迭代器,因此函数使用了它而不是vector。@ PJF如果你可以考虑用它来替换它:<代码> Cudio.Type()(map(x x.No.L..)).Max()。unRePAPIOR(0)
    您也可以将您的用例添加到问题中:)这是可行的,但我很难理解语义。我知道,
    Iterator
    是一种特性(因此可以是实现该特性的任何东西),但在此上下文中,我对
    impl
    关键字感到困惑。我们以前没有过它,但它怎么会有已知的大小?我建议阅读。基本上,它与
    fn max_width(strings:t)相同->usize
    。哦!所以
    Iterator
    是特性本身,而
    impl Iterator
    是实现该特性的东西。非常感谢!!谢谢@Tom。我认为这与旧链接相匹配。我更喜欢这个答案,因为它还提供了一个接近OP最初意图的解决方案,使用动态多态性。