球魚
let add_one_v2 = |x: u32| -> u32 { x + 1 };
fn add_one_v1 (x: u32) -> u32 { x + 1 }
let add_one_v3 = |x| { x + 1 };
let add_one_v4 = |x| x + 1 ;
fn main () {
let example_closure = |x| x;
let s = example_closure(String::from("hello"));
let n = example_closure(5);
}
如果不寫型態的話
會依第一次呼叫時,傳進來的型態為依據
之後的呼叫要和第一次傳進來的型態一樣
error[E0308]: mismatched types
--> src/main.rs:5:29
|
5 | let n = example_closure(5);
| ^
| |
| expected struct `std::string::String`, found integral variable
| help: try using a conversion method: `5.to_string()`
|
= note: expected type `std::string::String`
found type `{integer}`
fn main() {
let x = 4;
let equal_to_x = |z| z == x;
let y = 4;
assert!(equal_to_x(y));
}
fn main() {
let x = 4;
fn equal_to_x(z: i32) -> bool { z == x }
let y = 4;
assert!(equal_to_x(y));
}
error[E0434]: can't capture dynamic environment in a fn item
--> src/main.rs:4:42
|
4 | fn equal_to_x(z: i32) -> bool { z == x }
| ^
|
= help: use the `|| { ... }` closure form instead
fn main() {
let x = vec![1, 2, 3];
let equal_to_x = move |z| z == x;
println!("can't use x here: {:?}", x);
let y = vec![1, 2, 3];
assert!(equal_to_x(y));
}
error[E0382]: use of moved value: `x`
--> src/main.rs:6:40
|
4 | let equal_to_x = move |z| z == x;
| -------- value moved (into closure) here
5 |
6 | println!("can't use x here: {:?}", x);
| ^ value used here after move
|
= note: move occurs because `x` has type `std::vec::Vec<i32>`, which does not implement
the `Copy` trait
fn main() {
let mut x = 1;
let mut add_to_x = move || {
x = x + 1;
println!("Fn x {:?}", x);
};
println!("x {:?}", x);
add_to_x();
println!("x {:?}", x);
add_to_x();
println!("x {:?}", x);
}
Compiling closure v0.1.0 (file:///home/ballfish/rusts/closure)
Finished dev [unoptimized + debuginfo] target(s) in 1.50 secs
x 1
Fn x 2
x 1
Fn x 3
x 1
struct Cacher<T>
where T: Fn(u32) -> u32
{
calculation: T,
value: Option<u32>,
}
impl<T> Cacher<T>
where T: Fn(u32) -> u32
{
fn new(calculation: T) -> Cacher<T> {
Cacher {
calculation,
value: None,
}
}
fn value(&mut self, arg: u32) -> u32 {
match self.value {
Some(v) => v,
None => {
let v = (self.calculation)(arg);
self.value = Some(v);
v
},
}
}
}
fn call_with_different_values() {
let mut c = Cacher::new(|a| a);
let v1 = c.value(1);
let v2 = c.value(2);
assert_eq!(v2, 2);
}
let v1 = vec![1, 2, 3];
let v1_iter = v1.iter();
for val in v1_iter {
println!("Got: {}", val);
}
pub trait Iterator {
type Item;
fn next(&mut self) -> Option<Self::Item>;
}
fn iterator_demonstration() {
let v1 = vec![1, 2, 3];
let mut v1_iter = v1.iter();
assert_eq!(v1_iter.next(), Some(&1));
assert_eq!(v1_iter.next(), Some(&2));
assert_eq!(v1_iter.next(), Some(&3));
assert_eq!(v1_iter.next(), None);
}
fn iterator_sum() {
let v1 = vec![1, 2, 3];
let v1_iter = v1.iter();
let total: i32 = v1_iter.sum();
assert_eq!(total, 6);
}
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]);
#[derive(PartialEq, Debug)]
struct Shoe {
size: u32,
style: String,
}
fn shoes_in_my_size(shoes: Vec<Shoe>, shoe_size: u32) -> Vec<Shoe> {
shoes.into_iter()
.filter(|s| s.size == shoe_size)
.collect()
}
#[test]
fn filters_by_size() {
let shoes = vec![
Shoe { size: 10, style: String::from("sneaker") },
Shoe { size: 13, style: String::from("sandal") },
Shoe { size: 10, style: String::from("boot") },
];
let in_my_size = shoes_in_my_size(shoes, 10);
assert_eq!(
in_my_size,
vec![
Shoe { size: 10, style: String::from("sneaker") },
Shoe { size: 10, style: String::from("boot") },
]
);
}
impl Iterator for Counter {
type Item = u32;
fn next(&mut self) -> Option<Self::Item> {
self.count += 1;
if self.count < 6 {
Some(self.count)
} else {
None
}
}
}
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);
pair (5, None) 因為 zip 會把 pair 成員中有 None 的 pair 視為 None 回傳,所以 (5, None) 不會被計算