【问题标题】:Define two traits such that a function must exist for the cartesian product of the two sets of types that implement it定义两个特征,使得实现它的两组类型的笛卡尔积必须存在一个函数
【发布时间】:2017-06-01 18:12:01
【问题描述】:

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

fn save(a, b)

必须为所有a : SaveSourceb : SaveDestination 实现(并且当向SaveSourceSaveDestination 添加新类型时,它必须为所有现有SaveDestinations 或@ 实现save 函数987654331@s.

这样的事情可能吗?如果没有,我可以使用什么来获得相同的结果吗?

【问题讨论】:

  • 我一定遗漏了你的问题; fn<A: SaveSource, B: SaveDestination>(a: A, b: B) { ... } 似乎已经按照你的要求做了。为什么其中任何一个特征本身都会实现该功能?
  • @Shepmaster:我不能为所有类型提供一个函数。所有类型对的实现都不同。
  • 你熟悉double dispatch pattern吗?
  • 如果所有的实现都必须不同,为什么 ab 实现 SaveSource / SaveDestination 特征很重要?
  • 设计traits,使通用功能可以仅使用traits上的方法来实现,并将实现的具体细节隐藏在实现之后。

标签: rust traits multiple-dispatch


【解决方案1】:

AB 的某些组合没有实现save 时,您不能强制编译器发出错误。但是你可以有一个通用函数,要求它接收到的特定AB 的组合实现save

为此,我们需要将save 包装在一个特征中,并在包含AB 的某种类型上实现它;最简单的选择是元组。 (不过,如果 trait 和类型不在同一个 crate 中,则连贯性可能会妨碍。)

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

【讨论】:

    猜你喜欢
    • 2017-03-05
    • 2016-02-24
    • 1970-01-01
    • 2015-06-16
    • 2020-11-03
    • 2012-01-03
    • 2019-08-26
    • 2020-12-10
    • 2015-07-29
    相关资源
    最近更新 更多