为什么不能使用`Self`来引用方法体中的枚举变体?

Cha*_*er5 13 enums rust

以下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指的是实现特征的任何类型.

Dan*_*ath 6

需要注意的一件重要事情是错误表示相关项目.enum Foo { Baz }没有相关的项目.特征可以有一个关联的项目:

trait FooBaz { type Baz }
//             ^~~~~~~~ - associated item
Run Code Online (Sandbox Code Playgroud)

总结一下:

为什么不能Self在这种情况下使用?

因为这个问题.RFC 2338尚未实现.

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)

我认为user4815162342最好地覆盖了其余的答案.


lje*_*drz 2

枚举构造函数!=关联项。

这是一个已知问题,但预计不会得到解决,至少在可预见的将来不会。根据我收集到的信息,让它发挥作用并非易事。此时相关文档或错误消息更有可能得到改进。

一般而言,我能找到的关于相关项目主题的文档很少;不过, 《Rust Book》有一章是关于关联类型的此外,这个相关问题Self中有很多很好的答案。