仅当满足类型约束条件时才有条件地实现 Rust 特性

Conditionally implement a Rust trait only if a type constraint is satisfied

我有以下结构:

pub struct Foo<T> {
    some_value: T,
}

impl<T> Foo<T> {
    pub fn new(value: T) -> Self {
        Self { some_value: value }
    }
}

// Implement `Default()`, assuming that the underlying stored type
// `T` also implements `Default`.
impl<T> Default for Foo<T>
where
    T: Default,
{
    fn default() -> Self {
        Self::new(T::default())
    }
}

如果 T 实现 Default,我希望 Foo::default() 可用,但 不可用 否则

是否可以在 Rust 中指定 "conditional implementation",当且仅当满足某些通用类型特征约束时我们才实现特征?如果不满足约束,则目标特征(在本例中为 Default)不会实现,并且不会出现编译器错误。

换句话说,是否可以通过以下方式使用上面的泛型结构?

fn main() {
    // Okay, because `u32` implements `Default`.
    let foo = Foo::<u32>::default();

    // This should produce a compiler error, because `Result` does not implement
    // the `Default` trait.
    //let bar = Foo::<Result<String, String>>::default();

    // This is okay. The `Foo<Result<...>>` specialisation does not implement
    // `Default`, but we're not attempting to use that trait here.
    let bar = Foo::<Result<u32, String>>::new(Ok(42));
}

您的示例在修复次要语法问题后确实有效:

pub struct Foo<T> {
    some_value: T,
}

impl<T> Foo<T> {
    pub fn new(value: T) -> Self {
        Self { some_value: value }
    }
}

// Implement `Default()`, assuming that the underlying stored type
// `T` also implements `Default`.
impl<T> Default for Foo<T>
where
    T: Default,
{
    fn default() -> Self {
        Self::new(T::default())
    }
}

fn main() {}

Playground

对于这个特定实例,derive(Default) 提供的实现完全符合您的要求:

#[derive(Default)]
pub struct Foo<T> {
    some_value: T,
}

另请参阅:

正如@Kornel 的回答所指出的,事实证明编译器已经 有条件地实现了通用结构的特性。

如果 T 满足在定义 Default 的实现时指定的类型约束,则 Default 特征仅对 struct Foo<T> 实现。在本例中,约束定义为 where T: Default。因此,如果 T 实现了 Default.

,那么 Foo<T> 只会实现 Default

如上面的 fn main() 示例所示,当 T 未实现 Default 时,任何使用 Foo<T>Default 实现的尝试都会产生编译器错误。