pubmod generate {usecrate::simulated;/* Generate the workout plan via an expensive calculation */pubfngenerate_work_out(intensity:u32,random_num:u32){ifintensity<25{println!("Today, do {} pushups!",simulated::simulated_expensive_calculation(intensity));println!("Next, do {} situps!",simulated::simulated_expensive_calculation(intensity));}else{ifrandom_num==3{println!("Take a break today!");}else{println!("Today, run {} minutes",simulated::simulated_expensive_calculation(intensity));}}}}mod simulated {usestd::time::Duration;usestd::thread;/* Try to simulate an expensive calculation */pubfnsimulated_expensive_calculation(num:u32)->u32{println!("calculating...");thread::sleep(Duration::from_secs(2));num}}
value 是 Option<i32> 类型的。在执行闭包之前,value 将是 None。如果使用 Cacher 的代码请求闭包的结果,这时会执行闭包并将结果储存在 value 字段的 Some 成员中。接着如果代码再次请求闭包的结果,这时不再执行闭包,而是会返回存放在 Some 成员中的结果。Cacher 结构体的字段是私有的,因为我们希望 Cacher 管理这些值而不是任由调用代码潜在的直接改变他们。
Iterator trait 有一系列不同的由标准库提供默认实现的方法;一些方法在其定义中调用了 next 方法,这也就是为什么在实现 Iterator trait 时要求实现 next 方法的原因。这些调用 next 方法的方法被称为 消费适配器(consuming adaptors),因为调用他们会消耗迭代器。
fn generate_workout(intensity: u32, random_number: u32) {
let expensive_result =
simulated_expensive_calculation(intensity);
if intensity < 25 {
println!(
"Today, do {} pushups!",
expensive_result
);
println!(
"Next, do {} situps!",
expensive_result
);
} else {
if random_number == 3 {
println!("Take a break today! Remember to stay hydrated!");
} else {
println!(
"Today, run for {} minutes!",
expensive_result
);
}
}
}
fn generate_workout(intensity: u32, random_number: u32) {
let expensive_closure = |num| {
println!("calculating slowly...");
thread::sleep(Duration::from_secs(2));
num
};
fn add_one_v1 (x: u32) -> u32 { x + 1 }
let add_one_v2 = |x: u32| -> u32 { x + 1 };
let add_one_v3 = |x| { x + 1 };
let add_one_v4 = |x| x + 1 ; // 单行代码不需要{}
error[E0308]: mismatched types
--> src/main.rs
|
| let n = example_closure(5);
| ^ expected struct `std::string::String`, found
integral variable
|
= note: expected type `std::string::String`
found type `{integer}`
// The even numbers from zero to ten.
let iter = (0..10).filter(|x| x % 2 == 0);
// We might iterate from zero to ten times. Knowing that it's five
// exactly wouldn't be possible without executing filter().
assert_eq!((0, Some(10)), iter.size_hint());
// Let's add five more numbers with chain()
let iter = (0..10).filter(|x| x % 2 == 0).chain(15..20);
// now both bounds are increased by five
assert_eq!((5, Some(15)), iter.size_hint());
let s1 = &[1, 2, 3];
let s2 = &[4, 5, 6];
let mut iter = s1.iter().zip(s2);
assert_eq!(iter.next(), Some((&1, &4)));
assert_eq!(iter.next(), Some((&2, &5)));
assert_eq!(iter.next(), Some((&3, &6)));
assert_eq!(iter.next(), None);
let a = [1, 2, 3];
let mut iter = a.into_iter().map(|x| 2 * x);
assert_eq!(iter.next(), Some(2));
assert_eq!(iter.next(), Some(4));
assert_eq!(iter.next(), Some(6));
assert_eq!(iter.next(), None);
let v1: Vec<i32> = vec![1, 2, 3];
let v2: Vec<_> = v1.iter().map(|x| x + 1).collect();
assert_eq!(v2, vec![2, 3, 4]);
#[test]
fn use_other_of_iterator() {
let sum: u32 = Counter::new().zip(Counter::new().skip(1))
.map(|(a, b)| a * b)
.filter(|x| x % 3 == 0)
.sum();
assert_eq!(18, sum);
}
/* Define the personal type to impl the Iterator trait */
#[derive(PartialEq, Debug)]
pub struct Pair<'a> {
id: u32,
name: &'a str,
count: u8,
}
/* The basic function for the Pair */
impl<'a> Pair<'a> {
pub fn new(id: u32, name: &'a str, count: u8) -> Pair {
Pair {id, name, count}
}
pub fn name(&self) -> &str {
self.name
}
pub fn id(&self) -> u32 {
self.id
}
}
impl<'a> Iterator for Pair<'a> {
type Item = (u32, &'a str); // Define the `next()` method return type
// Use the method of the `Iterator` trait to get the
// element tuple for six times
fn next(&mut self) -> Option<Self::Item> {
self.count += 1;
if self.count < 6 {
Some((self.id, self.name))
} else {
None
}
}
}