代码之家  ›  专栏  ›  技术社区  ›  Lukas Kalbertodt

关联型超性状的别名

  •  2
  • Lukas Kalbertodt  · 技术社区  · 6 年前

    我有以下特点:

    use std::ops::Index;
    
    trait Map: Index<<Self as Map>::Key> {
        type Key;
    }
    

    Index 具有关联的类型 Output . 我在语义上想要这种类型,但我不喜欢这个名字 产量 在我的API中。因此,我想为该类型添加一个别名。

    我尝试了这个方法(对于普通类型别名使用相同的语法):

    trait Map: Index<<Self as Map>::Key> {
        type Key;
        type Value = <Self as Index<Self::Key>>::Output;
    }
    

    但是,这会导致错误:

    error[E0658]: associated type defaults are unstable (see issue #29661)
     --> src/main.rs:9:9
      |
    9 |         type Value = <Self as Index>::Output;
      |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    

    the tracking issue 我可以理解,这种语法显然用于可以被实现者覆盖的关联类型。但我不希望实现人员覆盖此类型,我始终希望 Map::Value == Map::Output

    这有可能吗?

    1 回复  |  直到 6 年前
        1
  •  2
  •   attdona    6 年前

    这个 associated item RFC 状态:

    特性的类型参数可以是“输入”或“输出”:

    • 输入。“input”类型参数用于确定要使用哪个impl。

    • 输出。“输出”类型参数由IMPL唯一确定,但在选择IMPL时不起作用。

    RFC还通过以下方式阐明了特征匹配:

    • 将所有特征类型参数视为输入类型,以及
    • 提供关联的类型,这些类型是输出类型。

    从这些描述中可以清楚地看到,关联类型是由 impl ,因此不可能阻止实现人员重写类型。

    获得对实现者某种形式控制的解决方法可能是定义使用关联类型的默认方法,例如:

    pub trait Map: Index<<Self as Map>::Key> {
        type Key;
        type Value = <Self as Index<<Self as Map>::Key>>::Output;
    
        #[doc(hidden)]
        fn invalid_operation() -> Option<&'static <Self as Index<<Self as Map>::Key>>::Output> {
            None
        }
    }
    

    现在,对于实现者来说,仅仅覆盖默认值是不可能的。 Value 类型,因为默认方法 invalid_operation 不再排字检查。

    还要注意 doc(hidden) 从文档中删除默认方法的功能。

    可以选择隐藏的方法名来传递一些信息。 对于上面的示例,实现者获取错误消息:

     error[E0399]: the following trait items need to be reimplemented as `Value` was overridden: `invalid_operation`
    

    如您所知,在当前稳定信任中不允许分配默认关联类型,必须使用夜间版本,并且必须使用以下功能启用该功能:

    #![feature(associated_type_defaults)]