楼主:
yam276 ('_')
2025-03-27 11:59:43: https://space.bilibili.com/361469957/lists/3902595
: 从入门到入门
1. Copy接口
fn copy_vs_move() {
let v: Vec<i32> = vec![0, 1, 2];
let n_ref: &i32 = &v[0];
let n: i32 = *n_ref;
let v: Vec<String> = vec![String::from("012")];
let s_ref: &String = &v[0];
let s: String = *s_ref;
}
i32 是基础类型,有 copy 接口,而 String 则没有
因此在 i32 进行 let n = *n_ref 的时候发生的是复制非转移所有权
而 String 进行 let s = *s_ref 的时候因为没有实现复制的接口,
因此会尝试获得所有权(他是 String 而非 &String )造成错误
因为基础型态有实现 copy 接口,所以可以自动解引用
但 String 本身是 Stack 指标储存资料在 Heap 的关系,
所以这边要让 let s = &v[0].clone() 或各种非借用方式来解决
2. 成员变量的所有权
fn tuple_fields() {
let mut name: (String, String) = (
String::from("Ferris"),
String::from("Rustacean")
);
let first: &String = &name.0;
name.1.push_str(", Esq.");
println!("{first} {}", name.1);
}
当使用 let first = &name.0 借用的时候,
name 本身与 name.0 成员失去可变性,
但 name.1 仍然可以借用也能可变借用
因为在 Rust 2018 版本以后,成员变量被当成独立个体,
而更之前的 Rust 版本这样则会编译错误,因为成员变量被当成整体
3. 承以上 code
fn tuple_fields() {
let mut name: (String, String) = (
String::from("Ferris"),
String::from("Rustacean")
);
let first: &String = get_first(&name);
name.1.push_str(", Esq.");
println!("{first} {}", name.1);
}
fn get_first(name: &(String, String)) -> &String {
&name.0
}
如果是这样,在 let first: &String = get_first(&name); 这行会编译错误,
因为 Rust 不管 Function 内的所有权实作,
因此编译器会判断 get_first(&name); 把整个 name 借走,
此时 name.1 即使在 function 内没被使用也被视为不可变
不过这只是现在版本的判断,有机会跟 2. 提到的一样,
新版本 Rust 如果让编译器变得更聪明了,
就有机会让它判断 function 内部是否有借用来让这段 code 通过,
但至于何时会这样更新,恐怕只有当事人自己知道了……