通用类型引用的Rust约束

时间:2016-04-21 04:08:19

标签: generics reference constraints rust

这里是场景:我有一个结构和特征对,如下所示:

trait Operation {
    fn operation(self) -> u32
}

struct Container<T: Sized + Operation> {
    x:T
}

impl <T: Sized + Operation> for Container<T> {
    fn do_thing(&self) -> u32 {
        // Do something with the field x.
    }
}

操作需要在使用时进行按值传递调用,并且问题出现与&#34; do_thing类似的任何内容。&#34;我宁愿不必为类型T强制执行复制语义,并希望为此解决此问题。基本上我想知道以下内容:

  1. 是否可以对类型参数的引用强制执行特征限制?类似于struct Container<T: Sized + Operation> where &T: Operation { ... }的内容。我尝试了一下语法,但我没有取得任何成功。
  2. 如果目前无法实现上述目标,理论上是否可行;即它没有违反任何要求的连贯属性或沿着那些方向的东西?
  3. 是否可以创建第二个特征,比如Middle: Operation,其中Middle可以要求MiddleT的任何实施者也需要实施Operation的{​​{1}}。
  4. 如果以上都不可能,还有其他常见的解决方法吗?
  5. 一些注释:

    • 我没有权限更改&T特征,它已经给出了,这也是我要与之合作的内容。
    • 有一个old RFC讨论了对where子句的一些修改,但我没有找到任何与引用约束相关的内容。
    • 编译器版本: rustc 1.8.0(db2939409 2016-04-11)

1 个答案:

答案 0 :(得分:9)

是的,您可以将&T限制为Sized + Operation。您需要使用Higher-Rank Trait Boundswhere

trait Operation {
    fn operation(self) -> u32;
}

struct Container<T>
    where for<'a> &'a T: Sized + Operation
{
    x: T,
}

impl<T> Container<T>
    where for<'a> &'a T: Sized + Operation
{
    fn do_thing(&self) -> u32 {
        self.x.operation()
    }
}

impl<'a> Operation for &'a u32 {
    fn operation(self) -> u32 {
        *self
    }
}

fn main() {
    let container = Container { x: 1 };
    println!("{}", container.do_thing());
}

打印

1