【问题标题】:Is it possible to declare a type alias inside a trait?是否可以在 trait 中声明类型别名?
【发布时间】:2020-11-24 15:10:17
【问题描述】:

现有语法允许我们为关联类型编写默认值:

trait Foo {
    type Bar = i32;
}

我想要类似 C++ 的东西:

trait Foo {
    typedef int Bar;
}

这不是有效的 Rust 代码,但试图表明我的意图:

trait Foo<T> {
    trait Trait = Into<T> + /* 10 other traits dependent on T */;
    
    fn foo(x: Type) -> Trait;
}

【问题讨论】:

  • 为什么你想要这个?你会如何使用它?
  • 第二个 sn-p 没有多大意义,即使是伪代码。可以将多个特征边界添加到关联类型,但不将约束的总和本身视为一种类型。也许您对this 感兴趣?
  • 您的示例用法对我来说没有意义。您有一个通用的 type T,然后您尝试将其视为特征,因为您向其添加了其他特征 (+ Clone)。这两个概念不兼容。
  • 创建一个继承自之前特征的新特征可能会解决这里真正的问题。
  • 为什么人们不赞成这个问题 — 我没有反对这个问题,但是看看自您发布以来在短时间内所做的 cmets 和编辑的数量.这个问题的原始形式非常不清楚。人们大概读过它,看到它不清楚,投反对票,然后继续他们的一天。为避免此类投反对票,请确保问题从一开始就非常清楚。

标签: rust traits type-alias


【解决方案1】:

虽然特征别名目前不稳定,但您可以模拟它们。要创建“别名”,请定义一个新的空特征并为所有满足您希望别名匹配的特征的类型编写一个全面的实现。例如:

trait Short<T>: Into<T> /* plus others */ {}
impl<T, U> Short<T> for U where U: Into<T> /* plus others */ {}

可以像使用别名一样使用新特征:

trait Foo<T> {
    // Ret is bound by Into<T> and other bounds provided by Short
    type Ret: Short<T>;

    fn example(&self) -> Self::Ret;
}

struct X;

impl Foo<u32> for X {
    type Ret = u8;  // compiles because u8 is Into<u32>

    fn example(&self) -> u8 {
        0
    }
}

【讨论】:

    【解决方案2】:

    不,从 Rust 1.48 开始,不能在 trait 中声明类型别名。

    改为使用现有的类型别名功能:

    type FooBar = i32;
    
    trait Foo {
        fn usage(&self, _: FooBar);
    }
    

    您的具体示例可以通过两个不稳定特征的组合来解决:

    #![feature(type_alias_impl_trait)]
    #![feature(trait_alias)] // Stable alternative available in link below.
    
    trait FooBar<T> = Into<T>; // And 10 other traits dependent on T
    
    trait Foo<T> {
        type Ret: FooBar<T>;
    
        fn example(&self) -> Self::Ret;
    }
    
    impl Foo<i32> for i32 {
        type Ret = impl FooBar<i32>;
    
        fn example(&self) -> Self::Ret {
            42
        }
    }
    

    另见:

    【讨论】:

    • 非常感谢。这绝对不是我想要的,但我有这个想法。 Rust方式就是这样一种卷曲方式。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-31
    • 2019-12-06
    相关资源
    最近更新 更多