定义两个特征,使得必须存在实现它的两组类型的笛卡尔积的函数

时间:2017-06-01 18:12:02

标签: rust traits multiple-dispatch

我想创建两个特征SaveSourceSaveDestination,这样当某些类型实现这些特征时,函数:

fn save(a, b)
必须为所有a : SaveSourceb : SaveDestination实施

(当新版本添加到SaveSourceSaveDestination时,必须实施save适用于所有现有SaveDestinationSaveSource s。

这样的事情是否可能?如果没有,我可以使用任何东西来获得相同的结果吗?

1 个答案:

答案 0 :(得分:1)

AB的某些组合未实现save时,您无法强制编译器发出错误。但是,您可以使用通用函数,该函数要求其接收的特定AB的组合实现save

为此,我们需要将save包裹在特征中,并在包含AB的某种类型上实现它;最简单的选择是元组。 (但是,如果特征和类型不在同一个箱子中,那么一致性可能会妨碍。)

trait Save {
    fn save(self);
}

struct Foo; // sample save source
struct Bar; // sample save destination

// save is defined for the combination of `Foo` and `Bar`
impl Save for (Foo, Bar) {
    fn save(self) {
        unimplemented!()
    }
}

// in order to call this, the type `(A, B)` must implement `Save`    
fn call_save<A, B>(a: A, b: B)
where
    (A, B): Save
{
    (a, b).save();
}

fn main() {
    // this call compiles because `impl Save for (Foo, Bar)` is present
    call_save(Foo, Bar);
}

您也可以参考:

trait Save {
    fn save(self);
}

struct Foo;
struct Bar;

impl<'a, 'b> Save for (&'a Foo, &'b Bar) {
    fn save(self) {
        unimplemented!()
    }
}

fn call_save<'a, 'b, A, B>(a: &'a A, b: &'b B)
where
    (&'a A, &'b B): Save
{
    (a, b).save();
}

fn main() {
    call_save(&Foo, &Bar);
}