Home > Back-end >  Default generic parameter that depends on an optional trait bound
Default generic parameter that depends on an optional trait bound

Time:11-21

I have an enum that can store either an owned or borrowed, like below. It is similar to std::borrow::Cow but doesn't actually provide clone-on-write functionality.

use std::borrow::Borrow;

enum RefOrOwned<'a, B, T>
where
    B: ?Sized,
    T: Borrow<B>,
{
    Ref(&'a B),
    Owned(T),
}

It can be used like this:

fn main() {
    let str = RefOrOwned::<str, String>::Ref("Hi :D");
}

I would like the compiler to infer the T type for me. I thought of using the std::borrow::ToOwned trait: if B: ToOwned<Owned = T>, then T should be set to B::Owned by default. Is this possible?

CodePudding user response:

You can declare the type as having a default of <B as ToOwned>::Owned, and B won't be required to implement ToOwned unless the default is actually used:

enum RefOrOwned<'a, B, T = <B as ToOwned>::Owned>
where
    B: ?Sized,
    T: Borrow<B>,
{
    Ref(&'a B),
    Owned(T),
}

However, this will only work when you specify the types explicitly, i.e. RefOrOwned::<str>. If you leave them inferred (RefToOwned::Ref("Hi :D")), the default won't be used. I don't think there is a way to force a default in such situation.

  • Related