创建一个通用于另一个通用结构的结构

时间:2016-11-01 20:30:42

标签: generics struct rust dereference

我正在尝试在Rust中创建一个结构,它本身就其他通用结构而言是通用的。这很令人困惑,所以希望这个例子能让事情变得更加清晰:

use std::ops::Deref;
use std::rc::Rc;

struct Foo<T: Deref> {
    val: T<i32>,
    other: i32,
}

impl<T> Foo<T> {
    pub fn new(&self, val: T<i32>, other: i32) -> Self {
        Foo {val: val, other: other}
    }
}

fn main() {
    let foo = Foo::new(Rc::new(0), 0);
}

playground

我希望能够通过使用Foo个对象或new对象调用Rc<i32>来创建Arc<i32>对象,具体取决于我是否需要线程安全。我尝试这个时遇到以下错误:error[E0109]: type parameters are not allowed on this type,因为编译器抱怨i32中的val: T<i32>,。这可能在Rust吗?如果是这样,我可以安全地调用i32上的方法,假设它会自动取消引用吗?

1 个答案:

答案 0 :(得分:3)

该语法没有意义,但此版本编译:

use std::ops::Deref;
use std::rc::Rc;
use std::sync::Arc;

struct Foo<T> {
    val: T,
    other: i32,
}

impl<T> Foo<T>
    where T: Deref<Target = i32>
{
    pub fn new(val: T, other: i32) -> Self {
        Foo {
            val: val,
            other: other,
        }
    }
}

fn main() {
    let foo = Foo::new(Rc::new(0), 0);
    let foo = Foo::new(Arc::new(0), 0);
}

请注意特征界限如何阅读:T: Deref<Target = i32>“任何T实施Deref Target i32”。

然后,您可以实现取消引用val的方法:

fn sum(&self) -> i32 {
    *self.val + self.other
}

一般来说,像

这样的概念
struct Foo<T> {
    val: T<i32>,
}

不会证明有用。仅仅因为某些内容已在i32上进行参数化并不意味着您可以使用i32 任何内容。同样,类型可以使用i32之外的内容进行参数化(或根本不进行参数化),并且仍然可以访问i32