简体   繁体   English

什么时候在方法中使用 self、&self 和 &mut self?

[英]When to use self, &self, &mut self in methods?

What is the difference between a method taking self and a method taking &self or even &mut self ?采用self的方法与采用&self甚至&mut self的方法有什么区别?

Eg例如

impl SomeStruct {
    fn example1(self) { }
    fn example2(&self) { }
    fn example3(&mut self) { }
}

Say I want to implement a method that pretty prints the struct to stdout, should I take &self ?假设我想实现一种将结构漂亮地打印到标准输出的方法,我应该采用&self吗? I guess self also works?我想self也有效? I'm not sure when to use what.我不确定什么时候使用什么。

From the example in the book (just split onto three separate paragraphs and marked to maybe make it clearer):书中的例子(只是分成三个单独的段落并标记为可能使其更清楚):

&self : We've chosen &self here for the same reason we used &Rectangle in the function version: we don't want to take ownership, and we just want to read the data in the struct, not write to it. &self :我们在这里选择&self的原因与我们在函数版本中使用&Rectangle原因相同:我们不想取得所有权,我们只想读取结构中的数据,而不是写入数据。

&mut self : If we wanted to change the instance that we've called the method on as part of what the method does, we'd use &mut self as the first parameter. &mut self :如果我们想更改我们调用该方法的实例作为方法的一部分,我们将使用&mut self作为第一个参数。

self : Having a method that takes ownership of the instance by using just self as the first parameter is rare; self :拥有一个通过仅使用self作为第一个参数来获取实例所有权的方法是罕见的; this technique is usually used when the method transforms self into something else and you want to prevent the caller from using the original instance after the transformation.当方法将 self 转换为其他内容并且您希望防止调用者在转换后使用原始实例时,通常会使用此技术。

Or in other words: the difference is exactly the same as SomeStruct , &SomeStruct , and &mut SomeStruct .或者换句话说:区别与SomeStruct&SomeStruct&mut SomeStruct

Say I want to implement a method that pretty prints the struct to stdout, should I take &self ?假设我想实现一个将结构体打印到标准输出的方法,我应该使用&self吗? I guess self also works?我猜self也有效?

As you can see, this is exactly a case for &self .如您所见,这正是&self的情况。 If you use self (or &mut self ) the method will likely still compile, but it can only be used in more restricted situations.如果您使用self (或&mut self )该方法可能仍会编译,但它只能在更受限制的情况下使用。

The other answer is good, but not complete.另一个答案很好,但不完整。 So, here's more info about self , &self and &mut self .所以,这里有更多关于self&self&mut self的信息。

Summary table汇总表

Short for短缺 Equivalent to相当于 Takes ownership?取得所有权? When to use?什么时候使用? Example例子
self self: Self a: A Yes是的 The code that calls this method should not able to reuse the object on which you call the method.调用此方法的代码不应重用您调用此方法的 object。 Invalidate an object because maybe you transform it into another .使 object 无效,因为您可能将其转换为另一个. Drop an object. Immutable data structures?放下一个 object。不可变的数据结构?
&self self: &Self a: &A No - immutably borrows否 - 不变地借用 For reading self or its fields.用于阅读self或其领域。 For printing something or compute a value based on multiple values of other copyable fields.用于打印某些内容或根据其他可复制字段的多个值计算一个值。
&mut self self: &mut Self a: &mut A No - mutable borrows否 - 可变借用 For reading or writing self and its fields.用于读取或写入self及其字段。 A function that updates the internal state of a data structure.更新数据结构内部 state 的 function。
mut self mut self: Sel mut a: A Yes是的 If you want to change what self points to.如果你想改变self指向的内容。 Not useful because it takes ownership.没有用,因为它需要所有权。

More notes更多笔记

  • Self is an alias for the type that the impl block is for. Selfimpl块所针对的类型的别名。
  • The rules of ownership and borrowing apply to self as they apply to any other parameter (see eg this answer )所有权和借用规则适用于self ,因为它们适用于任何其他参数(参见例如这个答案
  • Examples of when to use which here and here何时使用 which herehere的示例
  • Examples of when we should take ownership here , although the answers don't provide code examples but just point to the docs我们应该在此处取得所有权的示例,虽然答案不提供代码示例,但仅指向文档
  • self is not just used as the first parameter of a method, but can also be used to reference the current module (more details here ) self不仅用作方法的第一个参数,还可以用于引用当前模块(更多细节在这里
  • If you define a variable like this let foo = Foo::new() (ie you cannot mutate foo ) and then you attempt to call a method that requires a mutable reference (ie the first parameter is &mut self ), you'll get a compilation error, so you would need to change let foo to let mut foo .如果你像这样定义一个变量let foo = Foo::new() (即你不能改变foo )然后你试图调用一个需要可变引用的方法(即第一个参数是&mut self ),你会得到编译错误,因此您需要将let foo更改为let mut foo A complete example here一个完整的例子在这里
  • More info also here更多信息也在这里

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM