何时在方法中使用 self、&self、&mut self?

Aar*_*man 9 rust

采取方法self和采取方法&self甚至是方法有什么区别&mut self

例如

impl SomeStruct {
    fn example1(self) { }
    fn example2(&self) { }
    fn example3(&mut self) { }
}
Run Code Online (Sandbox Code Playgroud)

假设我想实现一种将结构体漂亮地打印到标准输出的方法,我应该采用&self吗?我猜self也有效?我不确定何时使用什么。

nbr*_*bro 9

另一个答案很好,但不完整。self因此,这里有关于、&self和的更多信息&mut self

汇总表

短缺 相当于 取得所有权? 什么时候使用? 例子
self self: Self a: A 是的 调用此方法的代码不应重用您调用该方法的对象。 使一个对象无效,因为您可能将其转换为另一个对象。放下一个物体。不可变的数据结构?
&self self: &Self a: &A 否——一成不变地借用 用于阅读self或其领域。 用于打印某些内容或根据其他可复制字段的多个值计算值。
&mut self self: &mut Self a: &mut A 否 - 可变借用 用于阅读或写作self及其领域。 更新数据结构内部状态的函数。
mut self mut self: Self mut a: A 是的 如果你想改变self指向的内容。没有用,因为它需要所有权。

更多笔记

  • Selfimpl是块所属类型的别名。
  • 所有权和借用规则适用于self任何其他参数(参见例如此答案
  • 何时使用which的例子在这里这里
  • 我们何时应该在这里取得所有权的示例,尽管答案没有提供代码示例,而只是指向文档
  • self不仅用作方法的第一个参数,还可以用于引用当前模块(更多详细信息请参见此处
  • 如果您定义这样的变量let foo = Foo::new()(即您不能 mutate foo),然后尝试调用需要可变引用的方法(即第一个参数是&mut self),您将收到编译错误,因此您需要更改let foolet mut foo。完整的例子在这里
  • 更多信息也在这里


Ale*_*nov 7

书中的例子(只是分成三个单独的段落并标记为可能使其更清楚):

&self:我们选择&self这里的原因与我们&Rectangle在函数版本中使用的原因相同:我们不想取得所有权,我们只想读取结构中的数据,而不是写入数据。

&mut self:如果我们想更改我们调用该方法的实例作为方法的一部分,我们将&mut self用作第一个参数。

self: 有一个方法通过使用self第一个参数来获取实例的所有权是罕见的;当方法将 self 转换为其他内容并且您希望防止调用者在转换后使用原始实例时,通常会使用此技术。

或者换句话说:差异与SomeStruct&SomeStruct、 和完全相同&mut SomeStruct

假设我想实现一种将结构体漂亮地打印到标准输出的方法,我应该采用&self吗?我猜self也有效?

如您所见,这正是&self. 如果您使用self(或&mut self) 该方法可能仍会编译,但它只能在更受限制的情况下使用。

  • 这实际上同样适用于非“self”参数(正如您在开头提到的)。 (2认同)