我正在实现处理一个长度是 k * n
并创建k
长度点 n
引用原始向量的一个片断。
struct Point<'a> {
values: &'a [f32],
}
impl<'a> Point<'a> {
pub fn new(values: &'a [f32]) -> Self {
Point { values }
}
pub fn dist_euclidian(&self, point: &Point) -> Result<f32, &str> {
unimplemented!()
}
}
当我试图测试它时
#[test]
fn test_euclidian_distance() {
let mut v1 = vec![7.0, 11.0];
let mut v2 = vec![40.0, -27.0];
let p1: Point = Point::new(&v1[..]);
let p2: Point = Point::new(&v2[..]);
assert!((p1.dist_euclidian(&p2).unwrap() - 50.32).abs() <= 0.01);
v1[0] = 0.0;
v1[1] = -4.0;
v2[0] = 8.0;
v2[1] = 100.0;
assert!((p1.dist_euclidian(&p2).unwrap() - 104.3072).abs() <= 0.01);
}
我得到以下错误信息
error[E0502]: cannot borrow `v1` as mutable because it is also borrowed as immutable
--> src/k_means/point.rs:56:9
|
51 | let p1: Point = Point::new(&v1[..]);
| -- immutable borrow occurs here
...
56 | v1[0] = 0.0;
| ^^ mutable borrow occurs here
...
61 | assert!((p1.dist_euclidian(&p2).unwrap() - 104.3072).abs() <= 0.01);
| -- immutable borrow later used here
error[E0502]: cannot borrow `v1` as mutable because it is also borrowed as immutable
--> src/k_means/point.rs:57:9
|
51 | let p1: Point = Point::new(&v1[..]);
| -- immutable borrow occurs here
...
57 | v1[1] = -4.0;
| ^^ mutable borrow occurs here
...
61 | assert!((p1.dist_euclidian(&p2).unwrap() - 104.3072).abs() <= 0.01);
| -- immutable borrow later used here
error[E0502]: cannot borrow `v2` as mutable because it is also borrowed as immutable
--> src/k_means/point.rs:58:9
|
52 | let p2: Point = Point::new(&v2[..]);
| -- immutable borrow occurs here
...
58 | v2[0] = 8.0;
| ^^ mutable borrow occurs here
...
61 | assert!((p1.dist_euclidian(&p2).unwrap() - 104.3072).abs() <= 0.01);
| --- immutable borrow later used here
error[E0502]: cannot borrow `v2` as mutable because it is also borrowed as immutable
--> src/k_means/point.rs:59:9
|
52 | let p2: Point = Point::new(&v2[..]);
| -- immutable borrow occurs here
...
59 | v2[1] = 100.0;
| ^^ mutable borrow occurs here
60 |
61 | assert!((p1.dist_euclidian(&p2).unwrap() - 104.3072).abs() <= 0.01);
| --- immutable borrow later used here
有没有一种安全的方法来做我想做的事?
很不幸,Rust的引用有一个类似于其他语言中存储 "通过引用 "的名字,但这不是它们的本质。Rust的引用是为了 暂时 视图到数据中,当你想把数据的使用限制在某个范围内,并防止它在这个范围外被使用。这与你在这里的需求正好相反。
如果你想保留一些东西。不要 对它使用临时引用。使用拥有的值来代替,它可以被永久地存储和移动。99%的情况下,把引用放在结构内部是个错误。
而不是试图保持一个临时借用的片断。&'a [f32]
储存一个拥有 Vec<f32>
或拥有的片子 Box<[f32]>
.
如果你希望点有两个维度,那么使用字段、2元素数组或元组会更有效。(f32, f32)
. 如果你想要一个小的,但可变的尺寸数,使用以下方法更有效 ArrayVec<[f32; 4]>
.