Enums 为什么可以';t`Self`用于指枚举';方法体中的变量?
此问题现已过时,因为此功能已实现Enums 为什么可以';t`Self`用于指枚举';方法体中的变量?,enums,rust,Enums,Rust,此问题现已过时,因为此功能已实现 以下防锈代码无法编译: enum Foo { Bar, } impl Foo { fn f() -> Self { Self::Bar } } 错误消息使我感到困惑: error[E0599]:在当前作用域中找不到类型为'Foo'的名为'Bar'的关联项 -->src/main.rs:7:9 | 7 | Self::Bar | ^^^^^^^^^ 这个问题可以通过使用Foo而不是Self来解决
以下防锈代码无法编译:
enum Foo {
Bar,
}
impl Foo {
fn f() -> Self {
Self::Bar
}
}
错误消息使我感到困惑:
error[E0599]:在当前作用域中找不到类型为'Foo'的名为'Bar'的关联项
-->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
指的是实现traits的任何类型。Enum构造函数!=相关项目
这是一个已知的问题,但预计不会得到解决,至少在可预见的未来不会。从我所收集到的信息来看,仅仅让它发挥作用并不是一件小事;此时,相关文档或错误消息更有可能得到改进
一般来说,我几乎找不到关于相关项目主题的文档;不过,铁锈书里有一章是关于这一点的。此外,关于中的
Self
有很多很好的答案。如果枚举名Foo
实际上很长,并且您希望避免在整个实现中重复它,那么您有两个选择:
。这将允许您在在模块级使用LongEnumName作为Short
末尾返回f
Short::Bar
,允许更短的在模块级别使用LongEnumName::*
条
如果忽略发布,导入将是内部的,不会影响模块的公共API。需要注意的一点是,错误表示关联项<代码>枚举Foo{Baz}没有关联的项。特征可以具有关联项:
trait FooBaz { type Baz }
// ^~~~~~~~ - associated item
总结如下:
为什么在这种情况下不能使用Self
因为。有
Self
似乎起到了类型别名的作用,尽管做了一些修改
在哪里可以使用Self
Self只能用于traits和impl
s。此代码:
struct X {
f: i32,
x: &Self,
}
产出如下:
错误[E0411]:在此范围内找不到类型“Self”
-->src/main.rs:3:9
|
3 | x:&Self,
|^^^^`Self`仅在traits和impls中可用
这可能是暂时的情况,将来可能会改变
更准确地说,Self
应仅用作方法签名的一部分(例如fn Self\u in\u Self\u 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
}
}
我认为。有一种方法可以使您的示例在没有任何其他更改的情况下工作。通过在主文件中添加以下内容,您可以在Rust的夜间构建中进行尝试:
#![feature(type_alias_enum_variants)]
您可以跟踪该功能在其稳定方面的进展。这现在是可能的。枚举有点奇怪,因为它们在类型和名称空间之间起作用。在本例中,Foo更像是一个名称空间。这就是说,这只是好奇还是妨碍你做你想做的事情?@PaoloFalabella
Self
的常见用法是减少类型名称的重复。我只是希望我可以在方法体中做同样的事情。我遇到了一些好文章。希望它能对您有所帮助。这个问题是关于以前缺少的功能,现在已经存在,因此不再相关。