这是一件让初学者头晕的事:range,&[],vec,[]中元素到底是引用还是值的类别?。Rust因为有自动解引用和自动引用的安排,很多场所到底是否用&,让人无所适从。
比如,以下例子,一个filter,一个map, 一个有&,一个没有。为什么?
let v = vec![1u64, 2, 3, 4, 5, 6];
let val = v.iter()
.enumerate()
.filter(|&(idx, _)| idx % 2 == 0) // ->& 一定得要!
.map(|(idx, val)| val)
.fold(0u64, |sum, acm| sum + acm);
一、vec
map: mv1、mv2、mv3=>ok
let v = vec![1u64, 2, 3, 4, 5, 6];
let mv1: Vec<_> = v.iter().map(|x| x * 2).collect();
let mv2: Vec<_> = v.iter().map(|&x| x * 2).collect();
let mv3: Vec<_> = v.iter().map(|x| *x * 2).collect();
//let mv4: Vec<_> = v.iter().map(|x| **x * 2).collect();=>error
特别地: iter_mut()=>&mut
let mut v = vec![1u64, 2, 3, 4, 5, 6];
let mv5: Vec<_> = v.iter_mut().map(|x| *x * 2).collect();
let mv6: Vec<_> = v.iter_mut().map(|&mut x| x * 2).collect();
filter: nv1,nv2,nv4=>ok
let v = vec![1u64, 2, 3, 4, 5, 6];
let nv1: Vec<_> = v.iter().filter(|&x| x % 2 == 0).collect();
let nv1_2: Vec<_> = v.iter().filter(|&&x| x % 2 == 0).collect();//&& ok
let nv2: Vec<_> = v.iter().filter(|x| *x % 2 == 0).collect();
//let nv3: Vec<_> = v.iter().filter(|x| x % 2 == 0).collect(); =>error!
let nv4: Vec<_> = v.iter().filter(|x| **x % 2 == 0).collect();
find: fv1,fv2,fv3 =>ok
let a = vec![1, 2, 3, 4];
let fv1 = a.iter().find(|&x| *x == 2);
let fv2 = a.iter().find(|&&x| x == 2);
let fv3 = a.iter().find(|x| **x == 2);
//let fv4 = a.iter().find(|x| x == 2);=>error!
assert_eq!(fv2, Some(&2));
二、range
map: rv1=>ok
let rg =1..20;
let rv1: Vec<_> = rg.map(|x| x * 2).collect();
//let rv2: Vec<_> = rg.map(|&x| x * 2).collect(); =>error!
//let rv3: Vec<_> = rg.map(|x| *x * 2).collect(); =>error!
//let rv4: Vec<_> = rg.map(|&x| *x * 2).collect(); =>error!
filter: v1,v2,v3=>ok
let v1: Vec<_> = (1..20).filter(|&x| x % 2 == 0).collect();
let v2: Vec<_> = (1..20).filter(|x| x % 2 == 0).collect();
let v3: Vec<_> = (1..20).filter(|x| *x % 2 == 0).collect();
//let v4: Vec<_> = (1..20).filter(|x| **x % 2 == 0).collect(); =>error
//let v5: Vec<_> = (1..20).filter(|&&x| x % 2 == 0).collect();=>error
find: fv2,fv3=>ok
let a = 1..20;
//let fv1 = a.find(|&x| *x == 2);=>error
let fv2 = a.find(|x| *x == 2);
let fv3 = a.find(|&x| x == 2);
//let fv4 = a.find(|x| x == 2);=>error
对于循还:
事实上:
// 以下会报错: for i in &rg
//for i in &rg{
// ....
//}
三、&[]
map: tv1,tv2,tv3=>ok
let test = &[1, 2, 3, 4];
let tv1: Vec<_> = test.iter().map(|x| x * 2).collect();
let tv2: Vec<_> = test.iter().map(|&x| x * 2).collect();
let tv3: Vec<_> = test.iter().map(|x| *x * 2).collect();
//let tv4: Vec<_> = test.iter().map(|x| **x * 2).collect();
filter: tv2,tv2-2,tv3,tv4=>ok
let test = &[1, 2, 3, 4];
//let tv1: Vec<_> = test.iter().filter(|x| x % 2 == 0).collect(); =>error
let tv2: Vec<_> = test.iter().filter(|&x| x % 2 == 0).collect();
let tv2_2: Vec<_> = test.iter().filter(|&&x| x % 2 == 0).collect();// && :OK
let tv3: Vec<_> = test.iter().filter(|x| *x % 2 == 0).collect();
let tv4: Vec<_> = test.iter().filter(|x| **x % 2 == 0).collect();
find: fv1,fv2,fv4=>ok
let a = &[1, 2, 3];
let fv1 = a.iter().find(|&&x| x == 2);
let fv2 = a.iter().find(|&x| *x == 2);
//let fv3 = a.iter().find(|&x| x == 2);
let fv4 = a.iter().find(|x| **x == 2);
assert_eq!(fv2, Some(&2));
四、&&[]
map: av1,av2,av3=>ok
let arr = &&[1, 2, 3, 4, 5, 6];
let av1: Vec<_> = arr.iter().map(|x| x * 2).collect();
let av2: Vec<_> = arr.iter().map(|&x| x * 2).collect();
let av3: Vec<_> = arr.iter().map(|x| *x * 2).collect();
//let av4: Vec<_> = arr.iter().map(|x| **x * 2).collect(); =>error!
filter: fv2、fv4、fv5=>ok
let arr: &&[i32; 6] = &&[1_i32, 2, 3, 4, 5, 6];
//let fv1: Vec<_> = arr.iter().filter(|x| x > 2_i32).collect();
let fv2: Vec<_> = arr.iter().filter(|&x| *x > 2_i32).collect();
//let fv3: Vec<_> = arr.iter().filter(|x| *x > 2_i32).collect();
let fv4: Vec<_> = arr.iter().filter(|x| *x > 2_i32).collect();
let fv5: Vec<_> = arr.iter().filter(|&&x| x > 2_i32).collect();
find: fv1,fv2,fv4 =>ok
let a = &&[1, 2, 3];
let fv1 = a.iter().find(|&&x| x == 2);
let fv2 = a.iter().find(|&x| *x == 2);
//let fv3 = a.iter().find(|&x| x == 2);
let fv4 = a.iter().find(|x| **x == 2);
assert_eq!(fv2, Some(&2));
五、array:[]
map:av1,av2,av3=>ok
let arr = [1, 2, 3, 4, 5, 6];
let av1: Vec<_> = arr.iter().map(|x| x * 2).collect();
let av2: Vec<_> = arr.iter().map(|&x| x * 2).collect();
let av3: Vec<_> = arr.iter().map(|x| *x * 2).collect();
//let av4: Vec<_> = arr.iter().map(|x| **x * 2).collect(); =>error
filter: fv2、fv4 =>ok
let arr: [i32; 6] = [1_i32, 2, 3, 4, 5, 6];
//let fv1: Vec<_> = arr.iter().filter(|x| x > 2_i32).collect(); //=>error
let fv2: Vec<_> = arr.iter().filter(|&x| *x > 2_i32).collect();
//let fv3: Vec<_> = arr.iter().filter(|x| *x > 2_i32).collect();// =>error
let fv4: Vec<_> = arr.iter().filter(|x| **x > 2_i32).collect();
find: fv1,fv2,fv3=>ok
let a = [1, 2, 3];
let fv1 = a.iter().find(|&&x| x == 2);
let fv2 = a.iter().find(|x| **x == 2);
let fv3 = a.iter().find(|&x| *x == 2);
assert_eq!(fv1, Some(&2));
position:
let a = [1, 2, 3];
assert_eq!(a.iter().position(|&x| x == 2), Some(1));