gpt4 book ai didi

rust - 在非泛型结构上调用特定特征实现

转载 作者:行者123 更新时间:2023-11-29 07:57:38 24 4
gpt4 key购买 nike

我有一个实现通用特征的非通用结构。当我在结构上调用函数时,出现以下错误:

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

我已经尝试添加类型注释和通用参数绑定(bind),但显然我做错了什么;我仍然无法编译它。我在其他地方有类似的代码,其中有一个通用结构可以工作,大概是因为结构和 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 `_`
}

请原谅糟糕的标题,但这是我所知道的描述问题的最佳方式。

最佳答案

您有多种选择。

  1. 您可以指定要在哪个特定特征上调用 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);
    }
  2. 您可以移动 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 {}
  3. 您可以添加 PhantomData 加入 NoOpDebugger并制作NoOpDebugger本身是通用的,因此每个 NoOpDebugger<M>只实现 Debugger<M>对于相同的 M .在您的示例中,M对于 NoOpDebugger将从对 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();
    }
  4. 如果 Debugger 的实现不要依赖M , 如果你不使用 Debugger作为特征对象,那么您可以将类型参数移动到需要它的方法,并在不需要它的方法上省略它。

    trait Debugger {
    fn attach(&mut self) {}
    fn step<M: Memory>(mem: &M) {}
    }

关于rust - 在非泛型结构上调用特定特征实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39812947/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com