【问题标题】:What am I doing wrong with the specialization feature?我在专业化功能上做错了什么?
【发布时间】:2021-09-21 22:13:00
【问题描述】:

我想创建一个结构来实现具有默认关联类型和函数的特征以及专门的特征实现。但是,在尝试从默认实现构造结构实例时出现错误。

这是一些代码,显示了我正在尝试做的事情。在 Rust 操场上试一试here

#![allow(incomplete_features)]
#![feature(specialization)]

pub trait Data {
    type Data;
    fn new() -> Self;
}

pub struct MyStruct<T> {
    pub data: <Self as Data>::Data,
}

// default implementation
impl<T> Data for MyStruct<T> {
    default type Data = u64;
    default fn new() -> Self {
        MyStruct::<T> {data: 1u64}
    }
}

// a specialized implementation
impl Data for MyStruct<i64> {
    type Data = u32;
    fn new() -> Self {
        MyStruct::<i64> {data: 1u32}
    }
}

这给出了错误:

error[E0308]: mismatched types
  --> src/lib.rs:16:30
   |
14 |     default type Data = u64;
   |     ------------------------ expected this associated type
15 |     default fn new() -> Self {
16 |         MyStruct::<T> {data: 1u64}
   |                              ^^^^ expected associated type, found `u64`
   |
   = note: expected associated type `<MyStruct<T> as Data>::Data`
                         found type `u64`

For more information about this error, try `rustc --explain E0308`.
error: could not compile `playground` due to previous error

错误描述非常笼统,我不确定自己做错了什么。我知道这是一个不完整的功能是有原因的,但我觉得我做错了什么,而不是这个功能有问题。

【问题讨论】:

  • 我可以将此添加到问题中,但以下代码可以编译。然而,这只会让我更加困惑。 Rust playground

标签: rust


【解决方案1】:

我认为这只是它不完整的一个例子(并且来自 cmets 甚至可能不支持这种情况)。这段代码直接来自Specialization RFC(据我的理解表明它应该可以工作)但它失败并出现类似的错误:

#![allow(incomplete_features)]
#![feature(specialization)]

trait Example {
    type Output;
    fn generate(self) -> Self::Output;
}

impl<T> Example for T {
    default type Output = Box<T>;
    default fn generate(self) -> Box<T> { Box::new(self) }
}

impl Example for bool {
    type Output = bool;
    fn generate(self) -> bool { self }
}
error[E0053]: method `generate` has an incompatible type for trait
  --> src/lib.rs:11:34
   |
6  |     fn generate(self) -> Self::Output;
   |                          ------------ type in trait
...
10 |     default type Output = Box<T>;
   |     ----------------------------- expected this associated type
11 |     default fn generate(self) -> Box<T> { Box::new(self) }
   |                                  ^^^^^^
   |                                  |
   |                                  expected associated type, found struct `Box`
   |                                  help: change the output type to match the trait: `<T as Example>::Output`
   |
   = note: expected fn pointer `fn(_) -> <T as Example>::Output`
              found fn pointer `fn(_) -> Box<T>`

Playground

【讨论】:

  • 实现可以专门针对相关类型或函数之一而不专门针对另一个,从而导致签名不匹配,这难道不是问题吗?
  • 关联类型应该完全可特化吗?”仍被列为 tracking issue 顶部的“未解决问题”(最初由 Niko 在 2020 年 4 月 1 日编辑添加) .
  • @eggyal 很好的发现!我想这一切都还悬而未决。我绝对可以相信错误的原因正如您所描述的那样。
  • 感谢@kmdreko 提供的更简单的错误示例。看起来这可能只是由于专业化不完整。
  • @eggyal 感谢您的链接。我想我可能需要重新考虑在我的代码中依赖专门的关联类型,因为措辞表明它甚至可以被删除。
猜你喜欢
  • 2013-10-21
  • 1970-01-01
  • 2013-09-29
  • 1970-01-01
  • 2023-01-26
  • 2011-05-08
  • 1970-01-01
  • 1970-01-01
  • 2021-03-24
相关资源
最近更新 更多