Function 如何编写使用迭代器的Rust函数?
我想编写一个函数,它接受迭代器并返回对迭代器执行的某些操作的结果。具体地说,我正在尝试迭代Function 如何编写使用迭代器的Rust函数?,function,iterator,rust,Function,Iterator,Rust,我想编写一个函数,它接受迭代器并返回对迭代器执行的某些操作的结果。具体地说,我正在尝试迭代HashMap的值: use std::collections::HashMap; fn find_min<'a>(vals: Iterator<Item=&'a u32>) -> Option<&'a u32> { vals.min() } fn main() { let mut map = HashMap::new();
HashMap
的值:
use std::collections::HashMap;
fn find_min<'a>(vals: Iterator<Item=&'a u32>) -> Option<&'a u32> {
vals.min()
}
fn main() {
let mut map = HashMap::new();
map.insert("zero", 0u32);
map.insert("one", 1u32);
println!("Min value {:?}", find_min(map.values()));
}
使用std::collections::HashMap;
fn find_min)->Option+'static:std::marker::Sized'不满足
-->src/main.rs:3:17
|
3 | fn find_min)->Option+'static'在编译时没有已知的常量大小
|
=help:trait`std::marker::Sized`未为`std::iter::Iterator src/main.rs:11:41实现
|
11 | println!(“最小值{:?}”,find_Min(map.values());
|^^^^^^^^^^^^^^^^^^^预期的特征std::iter::Iterator,找到结构`std::collections::hash_map::Values`
|
=注意:应为'std::iter::Iterator+'静态类型`
找到类型`std::collections::hash_map::Values要在此处使用泛型:
fn find_min<'a, I>(vals: I) -> Option<&'a u32>
where
I: Iterator<Item = &'a u32>,
{
vals.min()
}
这种行为与Python背景相比有点不直观,而不是C++背景,所以让我稍微澄清一下。
在Rust中,值在概念上存储在绑定它们的名称中。因此,如果你写
let mut x = Foo { t: 10 };
let mut y = x;
x.t = 999;
let x: Iterator<Item=&'a u32>;
y.t
仍将是10
所以当你写作的时候
let mut x = Foo { t: 10 };
let mut y = x;
x.t = 999;
let x: Iterator<Item=&'a u32>;
让x:Iterator
。即使这是可能的,也不会有效率
因此,Rust所做的是为您提供
- 将值放在堆上,例如使用
Box
,这提供了Python风格的语义。然后,您可以使用&mut迭代器进行一般性处理,因为Rust 1.26是可用的。不太详细的版本
使用std::collections::HashMap;
fn find_min)->OptionI离我们太近了。具体来说,与泛型的区别在于静态分派,也就是说,Rust为每个我称之为?Correct的具体类型创建此函数的一个版本。通过这种方式,编译器知道迭代器的类型,因此它知道迭代器的大小,因此它知道需要保留多少内存。另外,类似于Iterator的类型注意,如果要将任意迭代器传递到函数中,则需要I
来实现Iterator
是绝对正确的,更通用的方法是需要I
来实现。它也允许您传递迭代器,但您也可以传递任何可以转换为迭代器的内容,而无需显式调用转换方法。“我认为这是使用迭代器和iterables的惯用方法。”弗拉基米尔马维耶夫,你能详细说明一下吗?我正试着用你的建议做如下的事情。。。有了foo:impl-Type
这就容易多了。这里的示例不会编译,let mut y=x赋值移动x,因此第3行不能再使用x。(除非您指定Foo是Copy,但这已经给出了一个很好的提示,表明它不会像您在脚本语言中期望的那样运行)无论“它是否更改了代码,或者它是否更改了您可以执行的操作”的语义如何,上面的示例代码仍然无效,并且不编译。我会假设它是非复制的,因为这是结构的默认值,并且在你的回答中没有提到它是复制的。问题是你用来推理的代码是无效的,没有一些初学者可能没有的任意假设。有没有理由说这不会比其他方法更好,或者只是最近的事?在Rust中,1.26 impl Trait被添加到了语言中。这是实现相同代码的一种不太冗长的方法