1. 函数参数传递
fn take_ownership(s: String) {
println!("I got ownership of: {}", s);
}
fn main() {
let s = String::from("hello");
take_ownership(s);
// 这里如果再使用 s 会报错,因为所有权已转移给 take_ownership 函数
// println!("{}", s); // 这行会导致编译错误
}
- 原理:当把一个具有所有权的值(如
String
)作为参数传递给函数时,所有权会转移到函数中。这是因为 Rust 的所有权系统规定,同一时刻只能有一个所有者。在这个例子中,s
在 main
函数中创建,当传递给 take_ownership
函数时,take_ownership
函数成为 s
的新所有者。函数结束后,s
会在 take_ownership
函数的作用域结束时被释放。
2. 函数返回值
fn give_ownership() -> String {
let s = String::from("world");
s
}
fn main() {
let new_s = give_ownership();
println!("I got: {}", new_s);
}
- 原理:函数返回值时,返回值的所有权从函数转移到调用者。在
give_ownership
函数中,s
被创建,当函数返回 s
时,所有权转移给 main
函数中的 new_s
。这样,s
在 give_ownership
函数结束后不会被释放,而是由 new_s
继续拥有并管理其生命周期。
3. 变量赋值
fn main() {
let s1 = String::from("rust");
let s2 = s1;
// 这里如果再使用 s1 会报错,因为所有权已转移给 s2
// println!("{}", s1); // 这行会导致编译错误
println!("{}", s2);
}
- 原理:当一个具有所有权的变量赋值给另一个变量时,所有权会发生转移。在这个例子中,
s1
创建后拥有字符串 rust
的所有权,当执行 let s2 = s1;
时,s1
的所有权转移给 s2
,s1
不再拥有该字符串的所有权,此时 s1
进入无效状态,不能再被使用。这保证了内存不会被重复释放,因为只有最后拥有所有权的变量在其作用域结束时才会释放内存。