我没有在文档中遇到Self
,只在源代码中。该文档仅使用self
。
答案 0 :(得分:63)
Self
是当前对象的类型。它可能出现在trait
或impl
中,但最常出现在trait
中,无论何种类型最终都会执行trait
(在定义trait
)时未知:
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
是trait
或impl
中用于方法的第一个参数的名称。使用其他名称是可能的,但是有一个显着的区别:
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`
}
答案 1 :(得分:40)
self
用作第一个方法参数时,是self: Self
的简写。还有&self
,相当于self: &Self
和&mut self
,相当于self: &mut Self
。
Self
是 syntactic sugar ,用于方法的接收类型(即此方法所在的类型impl
)。这也允许通用类型而不需要太多重复。
答案 2 :(得分:0)
if (
this instanceof Highcharts.seriesTypes.networkgraph &&
e.options.id === 'lang-tree'
) {
e.options.data.forEach(function (link) {
if (link[0] === 'Parent') {
nodes['Parent'] = {
id: 'Parent',
marker: {
radius: 20
}
};
nodes[link[1]] = {
id: link[1],
marker: {
radius: 10
},
color: colors[i++]
};
} else if (nodes[link[0]] && nodes[link[0]].color) {
nodes[link[1]] = {
id: link[1],
color: nodes[link[0]].color
};
}
});
e.options.nodes = Object.keys(nodes).map(function (id) {
return nodes[id];
});
}
}
是指实现特征的当前类型,另一方面,Self
是指方法参数中的实例,它应该是第一个参数。