首页 文章

为什么't `Self` be used to refer to an enum'方法体中的变体?

提问于
浏览
12

以下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 回答

  • 5

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

    trait FooBaz { type Baz }
    //             ^~~~~~~~ - associated item
    

    总结一下:

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

    因为this issue . RFC 2338not been implemented yet .

    Self 似乎充当了类型别名,尽管有一些修改 .

    Self在哪里可以使用?

    自我只能用于特质和 impl . 这段代码:

    struct X {
        f: i32,
        x: &Self,
    }
    

    输出以下内容:

    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
    

    这可能是暂时的情况,将来可能会发生变化!

    更准确地说, 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
        }
    }
    

    我想user4815162342 covered the rest of the answer best .

  • 3

    如果枚举名称 Foo 实际上很长,并且您希望避免在实现中重复它,则有两个选项:

    • use LongEnumName as Short 在模块级别 . 这将允许您在 f 结束时返回 Short::Bar .

    • use LongEnumName::* 在模块级别,允许更短的 Bar .

    如果省略 pub ,则导入将是内部的,不会影响模块的公共API .

  • 1

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

    它是一个众所周知的issue,但预计不会被修复,至少在可预见的未来不会 . 从我收集的内容来看,让这个工作起来并不是一件容易的事 . 此时,更有可能改进相关文档或错误消息 .

    关于相关项目的主题我几乎找不到文件;不过,Rust Book有一章关于associated types . 另外,在this related question中有很多关于 Self 的好答案 .

相关问题