离开作用域自动析构,这一点很像 c++ 的 RAII (Resource Acquisition Is Initialization), 只不过 rust 是离开作用域调用 drop trait
所有权
1 2 3 4 5 6
fnmain() { let s1 = String::from("hello"); let s2 = s1;
println!("s1 = {}, s2 = {}", s1, s2); }
这段代码,如果是 go 肯定可以运行,但是 rust 不行
1 2 3 4 5 6 7 8 9 10 11 12
hello_cargo# cargo run Compiling hello_cargo v0.1.0 (/root/zerun.dong/code/rusttest/hello_cargo) error[E0382]: borrow of moved value: `s1` --> src/main.rs:5:34 | 2 | let s1 = String::from("hello"); | -- move occurs because `s1` has type `String`, which does not implement the `Copy` trait 3 | let s2 = s1; | -- value moved here 4 | 5 | println!("s1 = {}, s2 = {}", s1, s2); | ^^ value borrowed here aftermove
执行报错,因为 s1 值的所有权己经 move 给 s2 了,原来的 s1 己经处于不可用状态。move occurs because s1 has type String, which does not implement the Copy trait
fnmain() { let s = String::from("hello"); // s comes into scope
takes_ownership(s); // s's value moves into the function... // ... and so is no longer valid here
let x = 5; // x comes into scope
makes_copy(x); // x would move into the function, // but i32 is Copy, so it's okay to still // use x afterward
} // Here, x goes out of scope, then s. But because s's value was moved, nothing // special happens.
fntakes_ownership(some_string: String) { // some_string comes into scope println!("{}", some_string); } // Here, some_string goes out of scope and `drop` is called. The backing // memory is freed.
fnmakes_copy(some_integer: i32) { // some_integer comes into scope println!("{}", some_integer); } // Here, some_integer goes out of scope. Nothing special happens.
这是官网的一个例子,当 takes_ownership 执行时,s 对应值的所有权就转移到函数中了,离开作用域后进行释放,如果 main 函数想再使用就会报错
但是同时,x 是一个 int 值,makes_copy 函数执行会 copy 这个 value, 而不是转移所有权
fnmain() { let d = Data{a:1,b:1}; test(d); println!("a is {}, b is {}", d.a, d.b); }
zerun.dong$ cargo run Compiling hello_cargo v0.1.0 (/Users/zerun.dong/code/rusttest/hello_cargo) error[E0382]: borrow of moved value: `d` --> src/main.rs:14:39 | 12 | let d = Data{a:1,b:1}; | - move occurs because `d` has type `Data`, which does not implement the `Copy` trait 13 | test(d); | - value moved here 14 | println!("a is {}, b is {}", d.a, d.b); | ^^^ value borrowed here after move
可以看到,运行报错,原因是 d 在调用 test 时己经 move 走了,所以 main 里不能再使用变量 d. 但问题在于 struct Data 成员都是整型啊,默认都是实现了 Copy 的