简体   繁体   English

我可以在 Rust 中定义一个带有自身类型参数的特征吗?

[英]Can I define a trait with a type parameter of itself in Rust?

I'm new to Rust and am having trouble working with traits and generics.我是 Rust 的新手,在使用特征和 generics 时遇到问题。 I started by defining a trait to do some work for me, then defined a generic struct that uses it as a type parameter.我首先定义了一个 trait 为我做一些工作,然后定义了一个将它用作类型参数的通用结构。 Now I realized that in the original trait, I actually want to use the struct I defined, so I'm in a kind of loop.现在我意识到在原始特征中,我实际上想使用我定义的结构,所以我处于一种循环中。 I'm not sure how to get out of it, and wondering if what I want is even possible via generics, or maybe I'll need to use boxing or some other method?我不知道如何摆脱它,想知道我想要的是否可以通过 generics 实现,或者我可能需要使用拳击或其他方法? Minimal example below.下面的最小示例。

This is what I started with initially:这是我最初开始的:

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

struct WorkResult {
  result: u64;
}

Next I realized I want to keep a worker on the result so I can lazily generate the the value and use various worker implementations.接下来我意识到我想在结果上保留一个工作人员,这样我就可以懒惰地生成值并使用各种工作人员实现。

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

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

This is where stuff started getting weird in the Worker trait.这就是Worker特质开始变得奇怪的地方。 WorkResult now needs a type parameter, but it's unknown in the trait. WorkResult现在需要一个类型参数,但它在 trait 中是未知的。 I tried a bunch of different methods, but can't get the compiler to like it.我尝试了一堆不同的方法,但无法让编译器喜欢它。

Attempt:试图:

trait Worker<T> where T: Worker {
  fn work() -> WorkResult<T>;
}

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

That didn't work at all.那根本行不通。 Compiler doesn't even recognize the parameter:编译器甚至无法识别参数:

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

I can't plug in any concrete type here (and I don't think I should have to).我不能在这里插入任何具体类型(我认为我不应该这样做)。 Is there any way to accomplish what I want here?有什么办法可以在这里完成我想要的吗?

The problem here is that the Worker trait needs a type parameter even when used as a bound, so you would need to write where T: Worker<U> .这里的问题是Worker trait 需要一个类型参数,即使用作边界也是如此,因此您需要编写where T: Worker<U>

Unfortunately, in the case of the trait definition, this would get recursive.不幸的是,在特征定义的情况下,这将是递归的。 For example, if you did:例如,如果您这样做:

trait Worker<T> 
    where T: Worker<U>,
{...}

You would then need to add a second generic parameter to worker, which would necessitate a third, and so on ad infinitum.然后,您需要向 worker 添加第二个通用参数,这需要第三个参数,以此类推。 The other possibility, where T: Worker<T> technically compiles, but it makes the trait impossible (or at the very least, beyond my ability) to successfully implement.另一种可能性, where T: Worker<T>技术上可以编译,但它使特征不可能(或至少超出我的能力)成功实现。

One potential solution would be to move the type parameter to the work function, like so:一种可能的解决方案是将类型参数移动到work function,如下所示:

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

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

(Note that struct WorkResult<T: Worker> is just shorthand for struct WorkResult<T> where T: Worker ) (注意struct WorkResult<T: Worker>只是struct WorkResult<T> where T: Worker的简写)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM