src/main.rs #[derive(Debug)] struct MyType { name: String } impl MyType { fn do_something(self, age: u32) { //等价于 fn do_something(self: Self, age: u32) { //等价于 fn do_something(self: MyType, age: u32) { println!("name = {}", self.name); println!("age = {}", age); } fn do_something2(&self, age: u32) { println!("do_something2 name = {}", self.name); println!("do_something2 age = {}", age); } } fn main() { let my_type = MyType{name: "linghuyichong".to_string()}; //使用self my_type.do_something(18); //等价于MyType::do_something(my_type, 18); my_type.do_something(81); // 编译不能通过哦 //println!("my_type: {:#?}", my_type); //在do_something中,传入的是对象,而不是引用,因此my_type的所有权就转移到函数中了,因此不能再使用 //使用&self let my_type2 = MyType{name: "linghuyichong".to_string()}; my_type2.do_something2(18); my_type2.do_something2(18); println!("my_type2: {:#?}", my_type2);//在do_something中,传入是引用,函数并没有获取my_type2的所有权,因此此处可以使用 println!("Hello, world!"); }
cargo build Compiling own v0.1.0 (/data2/rust/self) error[E0382]: use of moved value: `my_type` --> src/main.rs:24:5 | 21 | let my_type = MyType{name: "linghuyichong".to_string()}; | ------- move occurs because `my_type` has type `MyType`, which does not implement the `Copy` trait 22 | //使用self 23 | my_type.do_something(18); //等价于MyType::do_something(my_type, 18); | ---------------- `my_type` moved due to this method call 24 | my_type.do_something(81); // | ^^^^^^^ value used here after move | note: this function consumes the receiver `self` by taking ownership of it, which moves `my_type` --> src/main.rs:7:21 | 7 | fn do_something(self, age: u32) { | ^^^^ error: aborting due to previous error
描述
有同学问到,在 Rust 的方法中,第一个参数为 & self,那么如果改成 self(不是大写的 Self)行不行,两者有什么区别。
&self,表示向函数传递的是一个引用,不会发生对象所有权的转移;
self,表示向函数传递的是一个对象,会发生所有权的转移,对象的所有权会传递到函数中。
例子
#[derive(Debug)]
struct MyType {
name: String
}
impl MyType {
fn do_something(self, age: u32) {
//等价于 fn do_something(self: Self, age: u32) {
//等价于 fn do_something(self: MyType, age: u32) {
println!("name = {}", self.name);
println!("age = {}", age);
}
fn do_something2(&self, age: u32) {
println!("name = {}", self.name);
println!("age = {}", age);
}
}
fn main() {
let my_type = MyType{name: "linghuyichong".to_string()};
//使用self
my_type.do_something(18); //等价于MyType::do_something(my_type, 18);
//println!("my_type: {:#?}", my_type); //在do_something中,传入的是对象,而不是引用,因此my_type的所有权就转移到函数中了,因此不能再使用
//使用&self
let my_type2 = MyType{name: "linghuyichong".to_string()};
my_type2.do_something2(18);
my_type2.do_something2(18);
println!("my_type2: {:#?}", my_type2);//在do_something中,传入是引用,函数并没有获取my_type2的所有权,因此此处可以使用
println!("Hello, world!");
}
说明
因为定义方法时,是不希望发生所有权的转移的,所以方法的第一个参数使用 & self 而不是 self