以下Rust代码无法编译:
enum Foo {
Bar,
}
impl Foo {
fn f() -> Self {
Self::Bar
}
}
Run Code Online (Sandbox Code Playgroud)
错误消息让我困惑:
error[E0599]: no associated item named `Bar` found for type `Foo` in the current scope
--> src/main.rs:7:9
|
7 | Self::Bar
| ^^^^^^^^^
Run Code Online (Sandbox Code Playgroud)
这个问题可以通过使用Foo而不是来解决Self,但这让我觉得奇怪,因为Self它应该引用正在实现的类型(忽略特征),在这种情况下是Foo.
enum Foo {
Bar,
}
impl Foo {
fn f() -> Self {
Foo::Bar
}
}
Run Code Online (Sandbox Code Playgroud)
为什么不能Self在这种情况下使用?哪里可以Self使用*?还有什么我可以用来避免在方法体中重复类型名称吗?
*我忽略了traits中的用法,其中Self指的是实现特征的任何类型.
需要注意的一件重要事情是错误表示相关项目.enum Foo { Baz }没有相关的项目.特征可以有一个关联的项目:
trait FooBaz { type Baz }
// ^~~~~~~~ - associated item
Run Code Online (Sandbox Code Playgroud)
总结一下:
为什么不能
Self在这种情况下使用?
Self 似乎是一个类型别名,虽然有一些修改.
哪里可以
Self使用?
自我只能用于特质和特征impl.这段代码:
struct X {
f: i32,
x: &Self,
}
Run Code Online (Sandbox Code Playgroud)
输出以下内容:
error[E0411]: cannot find type `Self` in this scope
--> src/main.rs:3:9
|
3 | x: &Self,
| ^^^^ `Self` is only available in traits and impls
Run Code Online (Sandbox Code Playgroud)
这可能是暂时的情况,将来可能会发生变化!
更确切地说,Self应仅用作方法签名的一部分(例如fn self_in_self_out(&self) -> Self)或访问相关类型:
enum Foo {
Baz,
}
trait FooBaz {
type Baz;
fn b(&self) -> Self::Baz; // Valid use of `Self` as method argument and method output
}
impl FooBaz for Foo {
type Baz = Foo;
fn b(&self) -> Self::Baz {
let x = Foo::Baz as Self::Baz; // You can use associated type, but it's just a type
x
}
}
Run Code Online (Sandbox Code Playgroud)