学习资料 :
English: Rust Book 4.1-4.4
简体中文: Rust语言圣经 - 所有权与借用
所有权
- 🌟🌟
fn main() {
// 使 用 尽 可 能 多 的 方 法 来 通 过 编 译
let x = String::from(“hello, world”);
let y = x;
println!(“{},{}”,x,y);
} - 🌟🌟
// 不 要 修 改 main 中 的 代 码
fn main() {
let s1 = String::from(“hello, world”);
let s2 = take_ownership(s1);
println!(“{}”, s2);
}
// 只 能 修 改 下 面 的 代 码!
fn take_ownership(s: String) {
println!(“{}”, s);
} - 🌟🌟
fn main() {
let s = give_ownership();
println!(“{}”, s);
}
// 只 能 修 改 下 面 的 代 码!
fn give_ownership() -> String {
let s = String::from(“hello, world”);
// convert String to Vec
// 将 String 转 换 成 Vec 类 型
let _s = s.into_bytes();
s
} - 🌟🌟
// 修 复 错 误 , 不 要 删 除 任 何 代 码 行
fn main() {
let s = String::from(“hello, world”);
print_str(s);
println!(“{}”, s);
}
fn print_str(s: String) {
println!(“{}”,s)
} - 🌟🌟
// 不 要 使 用 clone, 使 用 copy 的 方 式 替 代
fn main() {
let x = (1, 2, (), “hello”.to_string());
let y = x.clone();
println!(“{:?}, {:?}”, x, y);
}
可变性
当所有权转移时,可变性也可以随之改变。 - 🌟
fn main() {
let s = String::from("hello, ");
// 只 修 改 下 面 这 行 代 码 !
let s1 = s;
s1.push_str(“world”)
} - 🌟🌟🌟
fn main() {
let x = Box::new(5);
let … // 完 成 该 行 代 码 , 不 要 修 改 其 它 行 !
*y = 4;
assert_eq!(*x, 5);
}
部分 move
当解构一个变量时,可以同时使用 move 和引用模式绑定的方式。当这么做时,部分 move 就会发生:变
量中一部分的所有权被转移给其它变量,而另一部分我们获取了它的引用。
在这种情况下,原变量将无法再被使用,但是它没有转移所有权的那一部分依然可以使用,也就是之前被
引用的那部分。
示例
fn main() {
#[derive(Debug)]
struct Person {
name: String,
age: Box,
}
let person = Person {
name: String::from(“Alice”),
age: Box::new(20),
};
// 通 过 这 种 解 构 式 模 式 匹 配 ,person.name 的 所 有 权 被 转 移 给 新 的 变 量name
// 但 是 , 这 里age
变 量 却 是 对 person.age 的 引 用, 这 里 ref 的 使 用 相 当 于: let age = &p
let Person { name, ref age } = person;
println!(“The person’s age is {}”, age);
println!(“The person’s name is {}”, name);
// Error! 原 因 是 person 的 一 部 分 已 经 被 转 移 了 所 有 权 , 因 此 我 们 无 法 再 使 用 它
//println!(“The person struct is {:?}”, person);
// 虽 然person
作 为 一 个 整 体 无 法 再 被 使 用 , 但 是person.age
依 然 可 以 使 用
println!(“The person’s age from person struct is {}”, person.age);
}
练习 - 🌟
fn main() {
let t = (String::from(“hello”), String::from(“world”));
let _s = t.0;
// 仅 修 改 下 面 这 行 代 码 , 且 不 要 使 用_s
println!(“{:?}”, t);
} - 🌟🌟
fn main() {
let t = (String::from(“hello”), String::from(“world”));
// 填 空 , 不 要 修 改 其 它 代 码
let (__, __) = __;
println!(“{:?}, {:?}, {:?}”, s1, s2, t); // -> “hello”, “world”, (“hello”, “world”)
}