我如何在Rust中编写这个C函数?

时间:2015-02-28 20:53:03

标签: pointers rust

我如何在Rust中编写下面的函数?有没有办法安全地写replace()或操作本身是不安全的? list不必是数组,向量也可以。这是我感兴趣的替代操作。

void replace(int *list[], int a, int b) {
    *list[a] = *list[b];
}

我想要以下行为:

int a = 1;
int b = 2;
int *list[] = { &a, &a, &b, &b };

*list[0] = 3;        // list has pointers to values: [3, 3, 2, 2]
replace(list, 2, 0); // list has pointers to values: [3, 3, 3, 3]
*list[0] = 4;        // list has pointers to values: [4, 4, 4, 4]

1 个答案:

答案 0 :(得分:1)

回答修改后的问题

Rust does not allow你有多个可变引用(别名)到同一个项目。这意味着你永远无法运行第三行的等价物:

fn main() {
    let mut a = 1;
    let vals = &[&mut a, &mut a];
}

这失败了:

cannot borrow `a` as mutable more than once at a time
  

使用Rc和RefCell怎么样?

Rc不允许我们改变价值:

  

不可变值上的引用计数指针类型。

(强调我的)

RefCell::borrow_mut不允许多次并发借阅:

  

如果当前借用了值,则会发生恐慌。

回答原始问题

它基本相同。我选择u8因为它更容易输入。 : - )

fn replace(v: &mut [&mut u8], a: usize, b: usize) {
    *v[a] = *v[b]
}

fn main() {
    let mut vals = vec![1,2,3,4];
    {
        let mut val_refs: Vec<&mut u8> = vals.iter_mut().collect();
        replace(&mut val_refs, 0, 3);
    }
    println!("{:?}", vals);
}

playpen link

Rust会进行边界检查,因此如果使用大于切片的索引进行调用,程序将会发生混乱,并且不会导致内存损坏。