Keyword self

source ·
Expand description

方法的接收者,或当前模块。

self 用于两种情况:引用当前模块和标记方法的接收者。

在路径中,self 可用于在 use 语句中或在访问元素的路径中引用当前模块:

use std::io::{self, Read};
Run

在功能上与以下内容相同:

use std::io;
use std::io::Read;
Run

使用 self 访问当前模块中的元素:

fn foo() {}
fn bar() {
    self::foo()
}
Run

self 作为方法的当前接收者,允许在大多数情况下省略参数类型。 除了这种特殊性,self 的用法与任何其他参数非常相似:

struct Foo(i32);

impl Foo {
    // 没有 `self`。
    fn new() -> Self {
        Self(0)
    }

    // 消耗 `self`。
    fn consume(self) -> Self {
        Self(self.0 + 1)
    }

    // 借用 `self`。
    fn borrow(&self) -> &i32 {
        &self.0
    }

    // 借用 `self` 可变。
    fn borrow_mut(&mut self) -> &mut i32 {
        &mut self.0
    }
}

// 必须使用 `Type::` 前缀调用此方法。
let foo = Foo::new();
assert_eq!(foo.0, 0);

// 这两个调用产生相同的结果。
let foo = Foo::consume(foo);
assert_eq!(foo.0, 1);
let foo = foo.consume();
assert_eq!(foo.0, 2);

// 使用第二种语法会自动处理借用。
let borrow_1 = Foo::borrow(&foo);
let borrow_2 = foo.borrow();
assert_eq!(borrow_1, borrow_2);

// 第二种语法也会自动处理可变借用。
let mut foo = Foo::new();
*Foo::borrow_mut(&mut foo) += 1;
assert_eq!(foo.0, 1);
*foo.borrow_mut() += 1;
assert_eq!(foo.0, 2);
Run

请注意,调用 foo.method() 时的这种自动转换不限于以上示例。 有关更多信息,请参见 Reference