简体   繁体   English

仅在满足类型约束的情况下有条件地实现Rust特质

[英]Conditionally implement a Rust trait only if a type constraint is satisfied

I have the following struct: 我有以下结构:

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

I would like Foo::default() to be available if T implements Default , but not available otherwise. 我希望如果T实现Default ,则Foo::default()可用,否则不可用。

Is it possible to specify "conditional implementation" in Rust, where we implement a trait if and only if some generic type trait constraint is satisfied? 是否可以在Rust中指定“条件实现”,只要且仅当满足某些通用类型特征约束时,才在其中实现特征? If the constraint is not satisfied, the target trait ( Default in this case) is not implemented and there is no compiler error. 如果不满足约束条件,则不会实现目标特征(在这种情况下为Default ),并且不会出现编译器错误。

In other words, would is it possible to use the generic struct above in the following way? 换句话说,是否可以通过以下方式使用上面的泛型结构?

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

For this specific instance, the implementation provided by derive(Default) does exactly what you've asked for: 对于此特定实例, derive(Default)提供的实现完全符合您的要求:

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

See also: 也可以看看:

Your example, after fixing minor syntax issues, does work: 解决了小语法问题后,您的示例可以正常工作:

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 操场

As pointed out by @Kornel's answer, it turns out the compiler already conditionally implements traits of generic structs. 正如@Kornel的答案所指出的,事实证明编译器已经有条件地实现了通用结构的特征。

The Default trait is only implemented for struct Foo<T> if T satisfies the type constraints specified when defining the implementation of Default . 仅当T满足定义Default的实现时指定的类型约束时, struct Foo<T>实现Default特质。 In this case, the constraints were defined as where T: Default . 在这种情况下,约束定义为where T: Default Therefore, Foo<T> only implements Default if T implements Default . 因此, Foo<T>仅实现Default如果T实现Default

As shown by the fn main() example above, any attempt to use the Foo<T> 's Default implementation when T does not implement Default produces a compiler error. 如上面的fn main()示例所示,当T不实现Default时使用Foo<T>Default实现的任何尝试都会产生编译器错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM