rust基本类型所有权已经实现了copy
例1
在 Rust 中,基本类型(如 i32、f64、bool 等) 实现了 Copy trait,这意味着它们在赋值或传递时会被复制,而不是移动所有权。因此,当你将 a 和 b 传递给 sum 函数时,它们的值会被复制,而原始变量 a 和 b 的所有权不会发生变化。
代码分析
fn sum(a: i32, b: i32) -> i32 {
a + b
}
fn main() {
let a = 3; // a 是一个 i32 类型,实现了 Copy trait
let b = 4; // b 是一个 i32 类型,实现了 Copy trait
let c = sum(a, b); // a 和 b 的值被复制,传递给 sum 函数
println!("{}", c); // 输出 7
println!("{}", a); // a 的所有权没有移动,仍然可以访问
}
关键点
-
Copytrait:i32是基本类型,实现了Copytrait。- 当一个类型实现了
Copytrait 时,它的值在赋值或传递时会自动复制,而不是移动所有权。
-
所有权规则:
- 对于实现了
Copy的类型,传递值给函数时不会发生所有权转移。 - 对于未实现
Copy的类型(如String、Vec等),传递值给函数时会移动所有权,原始变量将无法再使用。
- 对于实现了
-
为什么可以输出
a:- 因为
a是i32类型,传递时是复制值,而不是移动所有权,所以a仍然有效。
- 因为
对比:未实现 Copy 的类型
如果你使用一个未实现 Copy 的类型(例如 String),情况会不同:
fn take_ownership(s: String) {
println!("{}", s);
}
fn main() {
let s = String::from("hello");
take_ownership(s); // s 的所有权被移动到函数中
println!("{}", s); // 这里会报错,因为 s 的所有权已经移动
}
总结
- 对于实现了
Copy的类型(如i32),传递值时是复制,所有权不会移动。 - 对于未实现
Copy的类型(如String),传递值时是移动所有权,原始变量将失效。
在你的代码中,a 和 b 是 i32 类型,因此它们的值被复制,所有权没有移动,所以最后仍然可以输出 a。
例2
在 Rust 中,& 是引用符号,用于创建一个值的引用(borrow),而不是直接传递值的所有权。具体到你的代码:
println!("{}, {}, {}", date, ¶ms.campus, ¶ms.position);
& 的作用
-
创建引用:
¶ms.campus和¶ms.position是对params.campus和params.position的引用。- 引用允许你访问值,而不需要获取值的所有权。
-
避免所有权转移:
- 如果
params.campus和params.position是未实现Copy的类型(例如String),直接传递它们会导致所有权转移。 - 使用
&可以避免所有权转移,保留原始变量的所有权。
- 如果
-
提高性能:
- 引用是轻量级的,只传递指针(内存地址),而不是复制整个值。
- 对于较大的数据结构(如
String或Vec),使用引用可以避免不必要的内存复制。
如果不加 & 会怎样?
如果不加 &,代码会尝试直接传递 params.campus 和 params.position 的所有权。具体行为取决于它们的类型:
情况 1:类型实现了 Copy trait
如果 params.campus 和 params.position 是实现了 Copy 的类型(例如 i32、bool 等),不加 & 不会有问题,因为它们的值会被复制,而不是移动所有权。
let campus: i32 = 42;
let position: i32 = 24;
println!("{}, {}", campus, position); // 没问题,因为 i32 实现了 Copy
情况 2:类型未实现 Copy trait
如果 params.campus 和 params.position 是未实现 Copy 的类型(例如 String),不加 & 会导致所有权转移,后续代码将无法再使用这些变量。
let campus = String::from("Main Campus");
let position = String::from("Building A");
println!("{}, {}", campus, position); // 这里没问题
println!("{}", campus); // 这里会报错,因为 campus 的所有权已经转移到 println!
错误示例
let campus = String::from("Main Campus");
let position = String::from("Building A");
println!("{}, {}", campus, position); // 所有权转移
println!("{}", campus); // 报错:value borrowed here after move
总结
- 加
&:创建引用,避免所有权转移,适用于未实现Copy的类型(如String)。 - 不加
&:- 对于实现了
Copy的类型(如i32),不会有问题。 - 对于未实现
Copy的类型(如String),会导致所有权转移,后续代码无法再使用这些变量。
- 对于实现了
在你的代码中,如果 params.campus 和 params.position 是 String 类型,建议使用 & 来避免所有权转移。如果它们是基本类型(如 i32),可以不加 &,但加上也不会出错。

浙公网安备 33010602011771号