如何将一个集合中的多个元素传递给一个或多个元素可变的函数?

HiD*_*der 5 collections vector rust

将两个元素从同一个向量传递给函数时,借用检查器将不允许其中一个元素是可变的.

struct Point {
    x: i32,
    y: i32,
}
fn main() {
    let mut vec: Vec<Point> = Vec::new();
    foo(&mut vec[0], &vec[1]);
}
fn foo(pnt_1: &mut Point, pnt_2: &Point) {
}
Run Code Online (Sandbox Code Playgroud)

错误:不能借用vec为不可变的,因为它也被借用为可变的

vec从来没有借过foo,vec[0]是借来的,vec[0]是一个Point.

如何将同一个集合中的多个元素传递给一个或多个元素可变的函数?

She*_*ter 7

如何将同一个集合中的多个元素传递给一个或多个元素可变的函数?

简短的回答是你不能,至少在没有集合本身支持的情况下.

Rust不允许使用可变别名 - 同一个东西的多个名称,其中一个允许变异.

使用编程语言的当前状态来验证(&mut vec[0], &vec[1])不会引入别名但(&mut vec[0], &vec[0])确实如此.增加复杂性的事实是[]操作符可以被重载,这允许创建一个类型,foo[0]并且foo[1]实际上指向相同的东西.

那么,一个集合怎么能帮忙呢?每个集合将以(或不具有)特定的方式以别名安全的方式细分.

可以存在这样的方法slice::split_at_mut,其验证两个半部不能重叠,因此不会发生混叠.

不幸的是,HashMap::get_two_things(&a, &b)我没有意识到这一点.这将是非常适合的,但这并不意味着它不可能存在.

vec从不被借用foo虽然

它肯定是.索引a时Vec,您将获得对内部某些内存块的引用Vec.如果Vec要在您下面进行更改,例如当有人添加或删除某个值时,则可能需要重新分配底层内存,从而使引用无效.这是为什么可变别名是一件坏事的一个主要例子.

  • @HiDefender要注意[XY问题](http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem).通常,问题可以通过惯用和高效的不同方式解决.这适用于大多数语言,而不仅仅是Rust!提出一个问题是合理的,你认为可以通过"一个集合中的多个元素,一个可变的元素"来解决,但允许社区在解决方案中有更多的回旋余地.正常的问题规则当然适用 - 创建[MCVE]并展示研究. (3认同)
  • @HiDefender:Rust不是"像C一样快",它是[**更快**](http://blog.burntsushi.net/ripgrep/)!虽然目前使用混叠来确保安全性,但它也可用于性能.数字库的Fortran内核今天仍在使用的主要原因是它们比C和C++内核更快.为什么他们更快?因为Fortran对别名更严格,所以为编译器提供了更多优化机会. (2认同)