【问题标题】:What's the difference between self and Self?自我和自我有什么区别?
【发布时间】:2015-08-31 05:39:24
【问题描述】:

我没有在文档中遇到Self,只是在源代码中。该文档仅使用self

【问题讨论】:

标签: rust


【解决方案1】:

Self 是当前对象的类型。它可能出现在traitimpl 中,但最常出现在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 是在 traitimpl 中用于方法的第一个参数的名称。可以使用其他名称,但是有一个显着的区别:

  • 如果使用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`
}

【讨论】:

  • 它可能出现在 trait 或 impl 中 - 它不能出现在“struct”中吗?
  • @jawanam:如果我尝试,我个人会得到 error: use of Self outside of an impl or trait。也许在更新的版本中取消了限制?
  • 不,目前不可能(截至 2015 年 9 月 1 日每晚)。自引用结构非常罕见,因此在这种情况下添加自处理被认为是低优先级的。
  • @Sergey.quixoticaxis.Ivanov:使用self 不是纯粹的语法,因为它是方法和关联函数之间的区别。对于普通的struct,调用方法或关联函数反过来主要是语法(尽管糖并没有那么糟糕)。但是,特征会发生变化:具体而言,特征对象(例如与 fn doit(d: &Display) 一起使用)只能在对象安全的特征上形成,并且关联的函数不是对象安全的(方法的子集也不安全)。
【解决方案2】:

self 当用作第一个方法参数时,是self: Self 的简写。还有&self,相当于self: &Self,还有&mut self,相当于self: &mut Self

方法参数中的

Self 是方法接收类型的语法糖(即impl 此方法所在的类型)。这也允许泛型类型没有太多重复。

【讨论】:

  • 把这个和java比较,我能把Self vs self看作是class vs this吗?
【解决方案3】:

Self 指的是实现 trait 的当前类型,另一方面,self 指的是实例。

self 作为第一个参数是rust 定义方法的方式。它只是将函数转换为方法的约定,就像在 python 中一样。在功能上,self 类似于 JavaScript 中的 this

对于那些不知道函数和方法之间区别的人来说,方法是附加到实例并通过该实例调用的函数。

【讨论】:

  • 这个答案有什么不正确的原因吗?假设它是准确的,我更喜欢它,因为它简洁,因此(对我而言)更容易初步理解和记住。
  • @JohnnyUtahh 不正确,还没有投票。
  • 知道了。并且很好的答案编辑,他们帮助 - 不失去第一句话的简洁性,这很棒。我投了赞成票。
猜你喜欢
  • 2011-04-08
  • 1970-01-01
  • 1970-01-01
  • 2012-12-07
  • 1970-01-01
  • 2015-10-16
  • 2018-05-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多