lambda - 用 Rust 编写的替代功能样式
问题描述
如何更正第 2 节中的语法错误?显示错误消息
error[E0277] slice indices are of type `usize` or ranges of `usize`
编译第 2 节时。(第 1 节和第 2 节;两者在不同的编程风格中具有相同的功能。)
extern crate rand;
use std::iter;
use rand::Rng;
fn estimateAreaCircleMonteCarlo() {
let box_area = 4.0;
let numIteration = 100000;
let mut x = Vec::<f64>::with_capacity(numIteration);
let mut y = Vec::<f64>::with_capacity(numIteration);
let mut distance = Vec::<f64>::with_capacity(numIteration);
let mut rng = rand::thread_rng();
x = iter::repeat(())
.map(|()| rng.gen_range(-1., 1.))
.take(numIteration)
.collect::<Vec<f64>>();
y = iter::repeat(())
.map(|()| rng.gen_range(-1., 1.))
.take(numIteration)
.collect::<Vec<f64>>();
// section 1, it is able to be compiled.
distance = (0..numIteration)
.map(|i| (x[i].powi(2) + y[i].powi(2)).sqrt())
.collect::<Vec<f64>>();
// section 2, same functionality as section 1 but it cannot be compiled.
// error[E0277]^^^^ slice indices are of type `usize` or ranges of `usize`
/*
distance = iter::repeat(())
.map(|i| (x[i].powi(2) + y[i].powi(2)).sqrt())
.take(numIteration)
.collect::<Vec<f64>>();
*/
println!("x={}", x[numIteration - 1]);
println!("y={}", y[numIteration - 1]);
println!("distance={}", distance[numIteration - 1]);
}
解决方案
iter::repeat(())
创建一个产生()
(单元类型)的迭代器。然后你用这个闭包映射那些迭代的项目:
|i| (x[i].powi(2) + y[i].powi(2)).sqrt()
i
因此是类型()
。你不能()
像编译器所说的那样索引一些东西:
the trait `std::slice::SliceIndex<[f64]>` is not implemented for `()`
解决此问题的一种方法可能是枚举:
distance = iter::repeat(()).enumerate()
.map(|(i, _)| (x[i].powi(2) + y[i].powi(2)).sqrt())
.take(numIteration)
.collect();
但是您的第一个解决方案更好,因为这些iter::repeat
东西没用。
请注意,如果您不需要保留x
s 和y
s,则会进行一些不必要的分配。这段代码可以简单地写成:
extern crate rand;
use rand::Rng;
fn estimate_area_circle_monteCarlo() {
let num_iteration = 100000;
let mut rng = rand::thread_rng();
let distances: Vec<_> = (0..num_iteration)
.map(|_| {
let x: f32 = rng.gen_range(-1., 1.);
let y: f32 = rng.gen_range(-1., 1.);
(x.powi(2) + y.powi(2)).sqrt()
})
.collect();
println!("last distance = {}", distances.last().unwrap());
}
collect
仅在您确实需要 a Vec
、 anHashSet
或其他内容时使用。如果您的目的是迭代某些数据,请保持迭代器不变。
推荐阅读
- javascript - React 将其链接为地图内的状态
- raspberry-pi3 - 是否可以通过 OpenPLC ModBus 控制 %QX0.0 LED 灯?
- sql - 如何修复“用于插入的 Sql 触发器不适用于声明变量”
- azure - 无法使用用户分配的托管标识检索 keyvault 机密
- excel - 如何使用 PowerShell 在列中搜索包含文本并在新列中返回数据?
- android - 如何通过 intent-filter 和 action.SEND_MULTIPLE 接收多个 vcard
- javascript - 显示当前标签 javascript
- java - 在 GWT 上的某个位置缩放图像
- docker - 如何实现对 docker-compose.yml 所做的更改以分离运行的容器
- json - STRING_ESCAPE json 正斜杠