以下Rust代码无法编译:
enum Foo {
Bar,
}
impl Foo {
fn f() -> Self {
Self::Bar
}
}
错误消息让我困惑:
error[E0599]: no associated item named `Bar` found for type `Foo` in the current scope
--> src/main.rs:7:9
|
7 | Self::Bar
| ^^^^^^^^^
可以通过使用 Foo
而不是 Self
来解决这个问题,但这让我很奇怪,因为 Self
应该引用正在实现的类型(忽略特征),在本例中是 Foo
.
enum Foo {
Bar,
}
impl Foo {
fn f() -> Self {
Foo::Bar
}
}
为什么不能在这种情况下使用 Self
?哪里可以使用 Self
*?还有什么我可以用来避免在方法体中重复类型名称吗?
*我忽略了traits中的用法,其中Self指的是实现特征的任何类型 .
3 回答
需要注意的一件重要事情是错误表示相关项目 .
enum Foo { Baz }
没有关联商品 . 特征可以有一个关联的项目:总结一下:
因为this issue . RFC 2338有not been implemented yet .
Self
似乎充当了类型别名,尽管有一些修改 .自我只能用于特质和
impl
. 这段代码:输出以下内容:
这可能是暂时的情况,将来可能会发生变化!
更准确地说,
Self
应仅用作方法签名的一部分(例如fn self_in_self_out(&self) -> Self
)或访问相关类型:我想user4815162342 covered the rest of the answer best .
如果枚举名称
Foo
实际上很长,并且您希望避免在实现中重复它,则有两个选项:use LongEnumName as Short
在模块级别 . 这将允许您在f
结束时返回Short::Bar
.use LongEnumName::*
在模块级别,允许更短的Bar
.如果省略
pub
,则导入将是内部的,不会影响模块的公共API .枚举构造函数!=关联项 .
它是一个众所周知的issue,但预计不会被修复,至少在可预见的未来不会 . 从我收集的内容来看,让这个工作起来并不是一件容易的事 . 此时,更有可能改进相关文档或错误消息 .
关于相关项目的主题我几乎找不到文件;不过,Rust Book有一章关于associated types . 另外,在this related question中有很多关于
Self
的好答案 .