advance/functional-programing/iterator #694
Replies: 17 comments 20 replies
-
萌新可以提个小建议吗? |
Beta Was this translation helpful? Give feedback.
-
typo 问题: 多了多 |
Beta Was this translation helpful? Give feedback.
-
use std::collections::HashMap;
fn main() {
let names = ["sunface", "sunfei"];
let ages = [18, 18];
let folks: HashMap<_, _> = names.into_iter().zip(ages.into_iter()).collect();
println!("{:#?}", names);
println!("{:#?}", ages);
println!("{:#?}", folks);
} |
Beta Was this translation helpful? Give feedback.
-
vec里面只有1,2,3 为什么sum是6 |
Beta Was this translation helpful? Give feedback.
-
高阶内容学习老费劲了,每一个板块都要一两天 |
Beta Was this translation helpful? Give feedback.
-
let result = match IntoIterator::into_iter(values) { |
Beta Was this translation helpful? Give feedback.
-
为什么 c 是不可变的变量 但在for循环中 c.count 可以发生改变 |
Beta Was this translation helpful? Give feedback.
-
这边提一下最后提及的循环展开(Loop Unrolling)和向量化是什么意思,首先阐明概念,循环展开是向量化的一种,向量化还包括有用SSE指令集这里不赘述 #include <stdio.h>
#include <windows.h>
#pragma comment(lib, "Winmm.lib") // for timeGetTime()
#define N 1000000000
int main() {
DWORD start, end;
start = timeGetTime();
int *a = (int *)malloc(N * sizeof(int));
// conventional loop
for (int i = 0; i < N; i++) {
a[i] = i;
}
end = timeGetTime();
printf("Conventional loop time: %d ms\n", end - start);
start = timeGetTime();
// unrolled loop
for (int i = 0; i < N; i += 4) {
a[i] = i;
a[i + 1] = i + 1;
a[i + 2] = i + 2;
a[i + 3] = i + 3;
}
end = timeGetTime();
printf("Unrolled loop time: %d ms\n", end - start);
return 0;
} 第二段unrolled loop耗时约为第一段未展开的1/4左右,因为循环中4个语句之间互不影响,所以编译器优化让他们同步执行 |
Beta Was this translation helpful? Give feedback.
-
fn sum_iter(x: &[f64]) -> f64 {
x.iter().sum::<f64>()
} 这里的 |
Beta Was this translation helpful? Give feedback.
-
学到这里 写GO 的又流下了眼泪 |
Beta Was this translation helpful? Give feedback.
-
虽然 但是, js里 for ... of 才是针对可迭代对象的语法 |
Beta Was this translation helpful? Give feedback.
-
Beta Was this translation helpful? Give feedback.
-
感觉拿js的for of对比更像一点 |
Beta Was this translation helpful? Give feedback.
-
转移所有权 let values = vec![1, 2, 3];
for v in values.into_iter() {
println!("{}", v)
}
// 下面的代码将报错,因为 values 的所有权在上面 `for` 循环中已经被转移走
// println!("{:?}",values);
let values = vec![1, 2, 3];
for v in values {
println!("{}", v)
}
// 下面的代码将报错,因为 values 的所有权在上面 `for` 循环中已经被转移走
// println!("{:?}", values); 借用 let values = vec![1, 2, 3];
for v in values.iter() {
println!("{}", v)
}
// 不会报错,因为 values_iter 只是借用了 values 中的元素
println!("{:?}", values);
let values = vec![1, 2, 3];
for v in &values {
println!("{}", v)
}
// 不会报错,因为 values_iter 只是借用了 values 中的元素
println!("{:?}", values); 可变借用 let mut values = vec![1, 2, 3];
// 对 values 中的元素进行可变借用
for v in values.iter_mut() {
*v = *v + 1;
}
// 输出[2, 3, 4]
println!("{:?}", values);
for v in &mut values {
*v = *v - 1;
}
// 输出[1, 2, 3]
println!("{:?}", values); |
Beta Was this translation helpful? Give feedback.
-
看了Iterator的源码,所有权和生命周期应该是编译器里的概念吧,实际在物理内存上并没有相应的变量,源码中用了各种底层的方法,像unsafe和unchecked。所以迭代器里面有很多概念不好理解,因为没有对应的底层实现,要死记硬背概念。下面简单举两个所有权和生命周期的例子(希望我的语言表述没问题)。 像数组的into_iter(self)方法,是标记了拿走数组所有权,实际上应该是每次调用next()时才具体的拿走每个元素的所有权,离开作用域才一个个元素去drop()。在for循环里,数组不能使用因为其所有权已经被拿走了,哪怕某些元素其实还没有被drop。 举例:如下代码无法编译,因为在for里面已经标记了数组整体的可变借用
|
Beta Was this translation helpful? Give feedback.
-
这两个bench mark test不是很严谨,其中产生随机数的代码,可能会导致计算结果的变动: fn rand_array(cnt: u32) -> Vec<f64> {
let mut rng = thread_rng();
(0..cnt).map(|_| rng.gen::<f64>()).collect()
}
#[bench]
fn bench_for(b: &mut Bencher) {
let samples = rand_array(LEN as u32);
b.iter(|| {
sum_for(&samples)
})
}
#[bench]
fn bench_iter(b: &mut Bencher) {
let samples = rand_array(LEN as u32);
b.iter(|| {
sum_iter(&samples)
})
} |
Beta Was this translation helpful? Give feedback.
-
习题在英文版:https://practice.course.rs/functional-programing/iterator.html |
Beta Was this translation helpful? Give feedback.
-
advance/functional-programing/iterator
https://course.rs/advance/functional-programing/iterator.html
Beta Was this translation helpful? Give feedback.
All reactions