关于rust:与-Rust-勾心斗角-快没有爱了

8次阅读

共计 1505 个字符,预计需要花费 4 分钟才能阅读完成。

基于 Rust 的 Vec 容器,能够表白数学里的 n 维点。上面的 foo 函数能够依据两个 n 维点 a 和 b,结构一个点集 {a, b, c},其中 c 是 a 和 b 的中点。

fn foo(a: &Vec<f64>, b: &Vec<f64>) -> Vec<Vec<f64>> {assert_eq!(a.len(), b.len());
    let mut c: Vec<f64> = Vec::new();
    for i in 0 .. a.len() {c.push(0.5 * (a[i] + b[i]));
    }
    let mut points: Vec<Vec<f64>> = Vec::new();
    points.push(a.clone());
    points.push(b.clone());
    points.push(c);
    return points;
}

留神,points 存储的是 ab 的正本,并非 ab 自身。假使我心愿 points 里存储的是 ab 自身,该如何做呢?我能想到的计划是

fn foo(a: &Vec<f64>, b: &Vec<f64>) -> Vec<&Vec<f64>> {assert_eq!(a.len(), b.len());
    let mut c: Vec<f64> = Vec::new();
    for i in 0 .. a.len() {c.push(0.5 * (a[i] + b[i]));
    }
    let mut points: Vec<&Vec<f64>> = Vec::new();
    points.push(a);
    points.push(b);
    points.push(&c);
    return points;
}

当初,points 存储的是 abc 的援用,然而 rustc 在编译这段代码时,会报错并指出,这个函数的返回值蕴含了一个借用值,然而函数签名却未能指明借用的是 a 还是 b。尽管代码写的很明确,ab 都被借用了,但即便如此,rustc 仍然无奈确定在 points 生命周期之内 ab 是否依然健在,因而须要通过生命周期标记通知 rustc,a 以及 b 的生命周期至多与 points 一样长,亦即

fn foo<'a>(a: &'a Vec<f64>, b: &'a Vec<f64>) -> Vec<&'a Vec<f64>> {... ... ...}

真正致命的问题在于 c,即

points.push(&c);

rustc 在编译这行代码时,会报错:

error[E0515]: cannot return value referencing local variable `c`

意思是,不能将一个局部变量的援用放在 points 里并将其返回。因为 foo 函数完结时,c 便寿终正寢,从而导致 points 对它的援用生效。我当初无奈解决这个问题,只好乖乖地回到了最后的计划,用 pointsab 所援用的点的正本,再存 c

当初,再来写一个函数 bar,用它批改 points,将 c 放在 ab 的两头:

fn bar(points: &mut Vec<Vec<f64>>) {let b = points[1];
    points[1] = points[2];
    points[2] = b;
}

逻辑上没问题,然而 rustc 认为,

move occurs because value has type `Vec<f64>`, which does not implement the `Copy` trait

意思就是 bar 外面的三条赋值语句,都是错的,起因是,Vec<f64> 没实现 Copy Trait。要 Copy 什么呢?我只是心愿 points 的第 2 个和第 3 个元素替换一下地位,并不想 Copy 什么啊。然而,我却不晓得该怎么写这个函数了,假使 points 存储的是援用,而不是理论的值,上述赋值语句应该是成立的,然而这又会导致 foo 函数难以定义。

感觉对 rust 快没有爱了……好在一开始就没有。

正文完
 0