是否可以在特征中声明类型别名?

Is it possible to declare a type alias inside a trait?

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

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

不,从 Rust 1.48 开始,无法在特征内声明类型别名。

而是使用现有的类型别名功能:

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

另请参阅:

  • Is there any way to create a type alias for multiple traits?

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

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