【问题标题】:Create a struct that is generic over another generic struct创建一个通用的结构,而不是另一个通用结构
【发布时间】:2017-03-15 01:39:23
【问题描述】:

我正在尝试在 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

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

【问题讨论】:

  • 与其他一些语言不同,不幸的是,Rust(还)没有更高种类的类型,所以类型参数必须是具体类型。但是在这种情况下,我同意@Shepmaster 你不需要它。

标签: generics struct rust dereference


【解决方案1】:

那个语法没有意义,但是这个版本可以编译:

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&lt;Target = i32&gt;“任何实现DerefTargeti32Target”。

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

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

一般来说,类似

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

不会被证明是有用的。仅仅因为某些东西在 i32 上被参数化并不意味着你可以用 i32 做任何事情。同样,一个类型可以用 i32 以外的东西参数化(或者根本不用),仍然可以让你访问 i32

【讨论】:

  • 太棒了,感谢您的帮助!现在要试试这个。我认为这将是一种更常见的技术,可以根据您的需要快速获得可以是线程安全或不安全的通用结构,您是否经常看到这种情况?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-11-06
  • 1970-01-01
  • 2018-07-23
  • 2021-11-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多