我有一个实现通用特征的非泛型结构。当我在struct上调用一个函数时,我收到以下错误:
error[E0282]: unable to infer enough type information about `_`
--> src/main.rs:35:18
|
35 | cpu.debugger.attach();
| ^^^^^^ cannot infer type for `_`
|
= note: type annotations or generic parameter binding required
我尝试过添加类型注释和泛型参数绑定,但我显然做错了;我仍然无法编译。我在其他地方有类似的代码,它有一个通用的结构,可能是因为struct和trait impl共享的泛型边界允许编译器推断出要调用的实际方法实现。
说明问题的最佳方法是使用简化示例:
struct Cpu<M: Memory, D: Debugger<M>> {
mem: M,
debugger: D,
}
impl<M: Memory, D: Debugger<M>> Cpu<M, D> {
fn new(mem: M, debugger: D) -> Self {
Cpu {
mem: mem,
debugger: debugger,
}
}
}
trait Memory {}
struct SimpleMemory;
impl Memory for SimpleMemory {}
trait Debugger<M: Memory> {
fn attach(&mut self) {}
fn step(mem: &M) {}
}
struct NoOpDebugger;
impl<M: Memory> Debugger<M> for NoOpDebugger {}
fn main() {
let mut cpu = Cpu::new(SimpleMemory, NoOpDebugger);
cpu.debugger.attach(); // <-- cannot infer type for `_`
}
请原谅这个糟糕的头衔,但这是我知道如何描述问题的最佳方式。
答案 0 :(得分:6)
您有几种选择。
您可以指定要调用attach
方法的特定特征。
fn main() {
let mut cpu = Cpu::new(SimpleMemory, NoOpDebugger);
Debugger::<SimpleMemory>::attach(&mut cpu.debugger);
}
或
fn main() {
let mut cpu = Cpu::new(SimpleMemory, NoOpDebugger);
<NoOpDebugger as Debugger<SimpleMemory>>::attach(&mut cpu.debugger);
}
您可以将attach
方法移动到非通用的超级链接。
trait DebuggerBase {
fn attach(&mut self) {}
}
trait Debugger<M: Memory>: DebuggerBase {
fn step(mem: &M) {}
}
impl DebuggerBase for NoOpDebugger {}
impl<M: Memory> Debugger<M> for NoOpDebugger {}
您可以将PhantomData
成员添加到NoOpDebugger
,并使NoOpDebugger
本身成为通用成员,这样每个NoOpDebugger<M>
仅对Debugger<M>
实施M
M
。在您的示例中,NoOpDebugger
的{{1}}将从Cpu::new
的调用中推断出来。
use std::marker::PhantomData;
struct NoOpDebugger<M>(PhantomData<M>);
impl<M: Memory> Debugger<M> for NoOpDebugger<M> {}
fn main() {
let mut cpu = Cpu::new(SimpleMemory, NoOpDebugger(PhantomData));
cpu.debugger.attach();
}
如果Debugger
的实现不依赖M
,并且您不使用Debugger
作为特征对象,则可以移动类型参数需要它的方法,并在不需要它的方法上省略它。
trait Debugger {
fn attach(&mut self) {}
fn step<M: Memory>(mem: &M) {}
}