【发布时间】:2015-08-31 05:39:24
【问题描述】:
我没有在文档中遇到Self,只是在源代码中。该文档仅使用self。
【问题讨论】:
标签: rust
我没有在文档中遇到Self,只是在源代码中。该文档仅使用self。
【问题讨论】:
标签: rust
Self 是当前对象的类型。它可能出现在trait 或impl 中,但最常出现在trait 中,它是最终实现trait 的任何类型的替身(定义@987654327 时未知@):
trait Clone {
fn clone(&self) -> Self;
}
如果我再执行Clone:
impl Clone for MyType {
// I can use either the concrete type (known here)
fn clone(&self) -> MyType;
// Or I can use Self again, it's shorter after all!
fn clone(&self) -> Self;
}
如果我很懒,我也可以在普通的impl 中使用它(它更短!):
impl MySuperLongType {
fn new(a: u32) -> Self { ... }
}
self 是在 trait 或 impl 中用于方法的第一个参数的名称。可以使用其他名称,但是有一个显着的区别:
self,则引入的函数是一个方法在 Rust 中,没有隐式的 this 参数传递给类型的方法:您必须显式地将“当前对象”作为方法参数传递。这将导致:
impl MyType {
fn doit(this: &MyType, a: u32) { ... }
}
正如我们所见,作为一种较短的形式,这也可能是(仍然很冗长):
impl MyType {
fn doit(this: &Self, a: u32) { ... }
}
这实际上是 &self 归结为幕后的内容。
impl MyType {
fn doit(&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 = MyType;
// Both can be used as an associated function
MyType::doit(&m, 1);
MyType::another(&m, 2);
// But only `doit` can be used in method position
m.doit(3); // OK: `m` is automatically borrowed
m.another(4); // ERROR: no method named `another`
}
【讨论】:
Self outside of an impl or trait。也许在更新的版本中取消了限制?
self 不是纯粹的语法,因为它是方法和关联函数之间的区别。对于普通的struct,调用方法或关联函数反过来主要是语法(尽管糖并没有那么糟糕)。但是,特征会发生变化:具体而言,特征对象(例如与 fn doit(d: &Display) 一起使用)只能在对象安全的特征上形成,并且关联的函数不是对象安全的(方法的子集也不安全)。
self 当用作第一个方法参数时,是self: Self 的简写。还有&self,相当于self: &Self,还有&mut self,相当于self: &mut Self。
Self 是方法接收类型的语法糖(即impl 此方法所在的类型)。这也允许泛型类型没有太多重复。
【讨论】:
Self 指的是实现 trait 的当前类型,另一方面,self 指的是实例。
将self 作为第一个参数是rust 定义方法的方式。它只是将函数转换为方法的约定,就像在 python 中一样。在功能上,self 类似于 JavaScript 中的 this。
对于那些不知道函数和方法之间区别的人来说,方法是附加到实例并通过该实例调用的函数。
【讨论】: