编写通用交换函数

die*_*_K3 3 rust

我正在尝试学习 Rust 并想编写一个简单的通用交换函数

fn swap<T>(i: &mut T, j: &mut T) {
    let tmp: T = *i;
    *i = *j;
    *j = tmp;
}
fn main() {
    let i: &int = &mut 5;
    let j: &int = &mut 6;
    println!("{} {}", i, j);
    swap(i, j);
    println!("{} {}", i, j);
}
Run Code Online (Sandbox Code Playgroud)

但是编译器会抛出错误消息:

helloworld.rs:2:18: 2:20 error: cannot move out of dereference of `&mut`-pointer
helloworld.rs:2     let tmp: T = *i;
                                 ^~
helloworld.rs:2:9: 2:12 note: attempting to move value to here
helloworld.rs:2     let tmp: T = *i;
                        ^~~
helloworld.rs:2:9: 2:12 help: to prevent the move, use `ref tmp` or `ref mut tmp` to capture value by reference
helloworld.rs:2     let tmp: T = *i;
                        ^~~
helloworld.rs:3:10: 3:12 error: cannot move out of dereference of `&mut`-pointer
helloworld.rs:3     *i = *j;
                         ^~
helloworld.rs:13:10: 13:11 error: cannot borrow immutable dereference of `&`-pointer `*i` as mutable
helloworld.rs:13     swap(i, j);
                          ^
helloworld.rs:13:13: 13:14 error: cannot borrow immutable dereference of `&`-pointer `*j` as mutable
helloworld.rs:13     swap(i, j);
                             ^
error: aborting due to 4 previous errors
Run Code Online (Sandbox Code Playgroud)

我真的是 Rust 的新手,我真的无法以任何方式处理这些错误。希望有人能解释哪里出了问题以及为什么。

Dan*_*mon 6

指针解引用的问题在于它违反了 Rust 的移动语义。您的函数正在借用iand 的引用j,即使您可以修改借用的值 - 例如:

fn assign<T>(i: &mut T, j: T) {
   *i = j;
}
Run Code Online (Sandbox Code Playgroud)

完全没问题——你不能将借来的值“移动”到其他地方,甚至是临时变量。这是因为借用仅在函数调用期间持续,并且通过移动值您将所有权转移给函数,这是不允许的。

解决这个问题的一种方法(不使用不安全代码)是复制值而不是移动它。您可以限制T实现Clonetrait,它允许您制作值的副本,而不影响原始借用的值:

fn swap<T: Clone>(i: &mut T, j: &mut T) {
    let tmp = i.clone();
    *i = j.clone();
    *j = tmp;
}
fn main() {
    let i: &mut int = &mut 5;
    let j: &mut int = &mut 6;
    println!("{} {}", i, j);
    swap(i, j);
    println!("{} {}", i, j);
}
Run Code Online (Sandbox Code Playgroud)

另请注意,我必须使用iand j &mut int,因为在您的代码中,您不可改变地借用了对值的引用。