2017-09-25 38 views
7

以下锈病代码无法编译:为什么`Self`不能用于引用方法体中的枚举变体?

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 
    } 
} 

为什么在这种情况下不能使用SelfSelf哪里可以使用*?还有什么我可以用来避免在方法体中重复类型名称?

*我忽略了性状的使用,其中Self指任何类型实现的特质。

+0

枚举有点奇怪,因为它们作用于类型和名称空间之间。在这种情况下,Foo更像是一个名称空间。这就是说,这只是好奇心,还是这阻止你做你想做的事情? –

+0

@PaoloFalabella这里'Self'的常用用法是减少类型名称的重复。我只是希望我能在方法体中做同样的事情。 – Challenger5

+0

我遇到了一些很好的文章,https://users.rust-lang.org/t/confused-by-use-of-self-in-example-in-chapter-17-of-rust-book-2nd-编辑/ 11394。希望它对你有所帮助。 – shri

回答

0

枚举建设者!=关联的项目。

这是一个已知的issue,但预计不会被固定,至少在可预见的将来不会。从我所收集到的信息来看,这并不是微不足道的,在这一点上,相关文档或错误信息更有可能得到改善。

关于相关项目一般;虽然,Rust书上有一章associated types。另外,关于Selfthis related question有很多很好的答案。

1

如果枚举名Foo在现实中是长,要避免在执行重复它,你有两个选择:

  • use LongEnumName as Short在模块级。这将允许您在f的末尾返回Short::Bar
  • use LongEnumName::*在模块级别,允许更短的Bar

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

1

重要的是要注意的是,错误说相关的项目。 enum Foo { Baz }没有关联的项目。的性状可以有相关的项目:

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

总结:

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

由于this issue

Self似乎充当类型别名,尽管进行了一些修改。

0123哪里可以使用Self

自我只能用于性状和impl s。此代码:

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

相关问题