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