结构方法
要在结构上声明方法(即,可以在 struct
上调用的函数,或者 struct
类型的值),创建一个 impl
块:
impl Foo {
fn fiddle(&self) {
// "self" refers to the value this method is being called on
println!("fiddling {}", self.my_string);
}
}
// ...
foo.fiddle(); // prints "fiddling hello"
&self
这里表示对 struct Foo
实例的不可变引用是调用 fiddle
方法所必需的。如果我们想要修改实例(例如更改其中一个字段),我们将改为使用 &mut self
(即可变引用):
impl Foo {
fn tweak(&mut self, n: isize) {
self.my_num = n;
}
}
// ...
foo.tweak(43);
assert_eq!(foo.my_num, 43);
最后,我们还可以使用 self
(注意缺少 &
)作为接收器。这要求实例由调用者拥有,并且在调用方法时将导致实例被移动。如果我们希望使用,销毁或以其他方式完全转换现有实例,这将非常有用。这种用例的一个例子是提供链接方法:
impl Foo {
fn double(mut self) -> Self {
self.my_num *= 2;
self
}
}
// ...
foo.my_num = 1;
assert_eq!(foo.double().double().my_num, 4);
请注意,我们还将 self
与 mut
作为前缀,以便我们可以在再次返回之前改变自我。double
方法的返回类型也需要一些解释。impl
块内的 Self
指的是 impl
适用的类型(在本例中为 Foo
)。在这里,它主要是避免重新键入类型的签名的有用简写,但在特征中,它可以用于引用实现特定特征的基础类型。
要为 struct
声明一个关联的方法 (在其他语言中通常称为类方法),只需省略 self
参数。这种方法在 struct
类型本身上调用,而不是在它的实例上调用:
impl Foo {
fn new(b: bool, n: isize, s: String) -> Foo {
Foo { my_bool: b, my_num: n, my_string: s }
}
}
// ...
// :: is used to access associated members of the type
let x = Foo::new(false, 0, String::from("nil"));
assert_eq!(x.my_num, 0);
请注意,只能为当前模块中声明的类型定义结构方法。此外,与字段一样,默认情况下所有结构方法都是私有的,因此只能由同一模块中的代码调用。你可以使用 pub
关键字为定义添加前缀,以使其可以从其他位置调用。