原文链接:https://blog.csdn.net/KeenCryp/article/details/84800856
“所有的trait都定义了一个隐式的类型Self,它指当前实现此接口的类型。” ——Rust官方文档
- 1
</pre>
self
当self
用作函数的第一个参数时,它等价于self: Self
。&self
参数等价于self: &Self
。&mut self
参数等价于self: &mut Self
。
Self
方法参数中的Self
是一种语法糖,是方法的接收类型(例如,本方法所在的impl
的类型)。
它可能出现在trait
或impl
中。但经常出现在trait
中,它是任何最终实现trait
的类型代替(在定义trait
时未知该类型)。
trait Clone {
fn clone(&self) -> Self;
}
我们有一个结构体类类型MyType
,它实现了这个trait
。
impl Clone for MyType {
//我可以使用具体类型(当前已知的,例如MyType)
fn clone(&self) -> MyType;
//或者再次使用Self,毕竟Self更简短
fn clone(&self) -> Self
}
self
是trait
或impl
中方法的第一个参数名。使用其他参数名是可能的,但有显著的差异:
- 若使用
self
,函数被称为方法(method) - 若使用任何其他名字,函数被称为关联函数(associated function)
在Rust中,没有隐式传递this
参数给某个类型的方法。你得显式将“当前对象”传递给方法参数。这将导致:
impl MyType {
fn doit(this &MyType, a : u32) { ... }
}
正如我们所见,作为一种较短的写法,这也可能(仍然冗长):
impl MyType {
fn doit(this &Self, a : u32) { ... }
}
因此,对照表:
Self => self: Self
&self => self: &Self
&mut self => self: &mut Self
但调用这些函数的方式变了:
impl MyType{
fn doit(&self, a: u32){
//...
}
fn another(this: &Self, a: u32){
//...
}
}
fn main() {
let m = Type;
//都可以用作关联函数
MyType::doit(&m, 1);
MyType::another(&m, 2)
//但只有”doit”可用作方法
m.doit(3) // m自动被借用
m.another(4) //错误:没有命名为`another`的方法
}
参考样例
样例来自《深入浅出Rust》,我稍加扩展,作为演示功能用。
fn main() {
let c = Circle {radius: 2f64};
println!("The area is {}",c.area());
println!("The area is {}",Circle::area2(&c))
}
trait Shape {
fn area(self: &Self) -> f64;
fn area2(this: &Self) -> f64;
}
struct Circle {
radius: f64,
}
impl Shape for Circle {
fn area(self: &Circle) -> f64 {
std::f64::consts::PI*self.radius*self.radius
}
fn area2(this: &Circle) -> f64 {
std::f64::consts::PI*this.radius*this.radius
}
}
- 区别
- 关联函数
- 方法
什么时候用关联函数,什么时候用方法?
原文出处
https://stackoverflow.com/questions/32304595/whats-the-difference-between-self-and-self
网友评论