有没有一种安全的方法让一个结构存储一个将在结构外被修改的向量的片断?

问题描述 投票:-1回答:1

我正在实现处理一个长度是 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 slice lifetime unsafe ownership
1个回答
2
投票

很不幸,Rust的引用有一个类似于其他语言中存储 "通过引用 "的名字,但这不是它们的本质。Rust的引用是为了 暂时 视图到数据中,当你想把数据的使用限制在某个范围内,并防止它在这个范围外被使用。这与你在这里的需求正好相反。

如果你想保留一些东西。不要 对它使用临时引用。使用拥有的值来代替,它可以被永久地存储和移动。99%的情况下,把引用放在结构内部是个错误。

而不是试图保持一个临时借用的片断。&'a [f32]储存一个拥有 Vec<f32> 或拥有的片子 Box<[f32]>.

如果你希望点有两个维度,那么使用字段、2元素数组或元组会更有效。(f32, f32). 如果你想要一个小的,但可变的尺寸数,使用以下方法更有效 ArrayVec<[f32; 4]>.

© www.soinside.com 2019 - 2024. All rights reserved.