主要为了解释这段代码:
impl Condition {
/// Returns an iterator over only the variable tests, along with
/// their indices.
/// 这个语法的解释可以参考这里 https://blog.katona.me/2019/12/29/Rust-Lifetimes-and-Iterators/
fn variables(&self) -> impl Iterator<Item = (usize, VariableID)> + '_ {
self.0
.iter()
.enumerate()
.filter_map(|(i, test)| match test {
ConditionTest::Variable(id) => Some((i, *id)),
ConditionTest::Constant(_) => None,
})
}
}
这里有三个问题:
- Iterator
- -> impl
- + '_
1.Iterator
参考文档 https://doc.rust-lang.org/book/ch13-02-iterators.html
最简单的用法
fn main(){
let v1 = vec![1, 2, 3];
//常规操作
for val in v1.iter() {
println!("Got: {}", val);
}
//求和,注意需要有::<i32>,否则会报错
println!("sum = {}", v1.iter().sum::<i32>());
//这里有map,由于iter是懒惰求值,必须有collect()才能生成有值的v2
let v2: Vec<_> = v1.iter().map(|x| x + 1).collect();
println!("v2 = {:#?}", v2)
}
实现Iterator trait:
struct Counter {
count: u32,
}
impl Counter {
fn new() -> Counter {
Counter { count: 0 }
}
}
impl Iterator for Counter {
type Item = u32;
fn next(&mut self) -> Option<Self::Item> {
if self.count < 5 {
self.count += 1;
//Some是Option<T>枚举
Some(self.count)
} else {
//None是Option<T>枚举
None
}
}
}
fn main() {
let mut counter = Counter::new();
assert_eq!(counter.next(), Some(1));
assert_eq!(counter.next(), Some(2));
assert_eq!(counter.next(), Some(3));
assert_eq!(counter.next(), Some(4));
assert_eq!(counter.next(), Some(5));
assert_eq!(counter.next(), None);
}
2.在返回值实现Iterator trait
trait Trait {}
impl Trait for i32 {}
fn returns_a_trait_object() -> impl Trait {
5
}
fn main(){
let x = returns_a_trait_object();
}
和
//第一种情况,返回值实现了Iterator特质,其中,Iterator的Item是str
fn to_words<'a>(text: &'a str) -> impl Iterator<Item = &'a str> {
//实际上这是split返回的Iterator
text.split(' ')
}
#[derive(Debug)]
struct AStruct{
x:i32,
y:i32,
}
impl AStruct{
fn new() -> Self{
Self{x:1,y:2}
}
fn get_iter_str<'a>(&self, text:&'a str) -> impl Iterator<Item = &'a str> {
text.split(' ')
}
}
fn main() {
let text = "word1 word2 word3";
for i in to_words(text){
println!("{}", i);
}
println!("{}", to_words("abc def ghi jkl").take(2).count());
let ast = AStruct::new();
println!("ast count = {:?}", ast.get_iter_str("sdff").count());
}
3.关于+'_
参考文献
- https://blog.katona.me/2019/12/29/Rust-Lifetimes-and-Iterators/ 完整的例子介绍
- https://doc.rust-lang.org/edition-guide/rust-2018/trait-system/impl-trait-for-returning-complex-types-with-ease.html#return-position 返回值实现trait
- https://doc.rust-lang.org/nightly/edition-guide/rust-2018/ownership-and-lifetimes/the-anonymous-lifetime.html 匿名lifetime '_
fn variables(&self) -> impl Iterator<Item = (usize, VariableID)> + '_ {
self.0
.iter()
.enumerate()
.filter_map(|(i, test)| match test {
ConditionTest::Variable(id) => Some((i, *id)),
ConditionTest::Constant(_) => None,
})
}
函数variables是Condition的成员函数。函数的返回值必须实现了Iterator特质,Iterator的type是tuple (usize, VariableID),后面的"+'_"表示,返回值的生命周期是Condition对象的生命周期。