在 Rust 中,我能否定义一个具有自身类型参数的 trait?

3
我是一名 Rust 新手,对特性和泛型的使用感到困惑。我首先定义了一个特性来帮我完成一些工作,然后定义了一个泛型结构体,将其作为类型参数使用。现在我意识到,在原始特性中,我实际上想要使用我定义的结构体,所以我陷入了一种循环中。我不确定如何摆脱它,并想知道通过泛型是否可能实现我想要的功能,或者也许我需要使用 boxing 或其他方法?下面是最简示例。
以下是我最初的代码:
trait Worker {
  fn work() -> WorkResult;
}

struct WorkResult {
  result: u64;
}

接下来,我意识到我想要在结果上保留一个工作线程,这样我就可以懒惰地生成值并使用各种工作线程实现。

trait Worker {
  fn work() -> WorkResult;
}

struct WorkResult<T> where T: Worker {
  result: u64;
  worker: T;
}

这是在Worker trait中开始变得奇怪的地方。现在WorkResult需要一个类型参数,但在trait中它是未知的。我尝试了许多不同的方法,但编译器似乎并不喜欢它。
trait Worker<T> where T: Worker {
  fn work() -> WorkResult<T>;
}

struct WorkResult<T> where T: Worker {
  result: u64;
  worker: T;
}

完全没有起作用。编译器甚至无法识别该参数:

error[E0107]: wrong number of type arguments: expected 1, found 0

我不能在这里插入任何具体类型(我认为我也不应该这样做)。有没有办法实现我想要的?


我很好奇你是否真的打算将work作为一个关联函数而不是一个方法。它应该在没有Worker实例的情况下被调用吗?但是为什么你在WorkResult内部还需要这个实例呢? - Cerberus
1个回答

1
这里的问题是,即使作为限定条件使用,Worker特质仍需要一个类型参数,因此您需要编写where T: Worker<U>
不幸的是,在特质定义的情况下,这将会变成递归的。例如,如果您这样做:
trait Worker<T> 
    where T: Worker<U>,
{...}

你需要向worker添加第二个泛型参数,这将需要第三个参数,以此类推。另一种可能性是where T: Worker<T>,从技术上讲可以编译,但它使得trait无法实现(或者至少超出了我的能力)。
一个潜在的解决方案是将类型参数移动到work函数中,像这样:
trait Worker {
    fn work<T: Worker>() -> WorkResult<T>;
}

struct WorkResult<T: Worker> {
    result: u64,
    worker: T,
}

(请注意,struct WorkResult<T: Worker> 只是 struct WorkResult<T> where T: Worker 的简写形式。)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接