简体   繁体   English

允许变量具有任何特征实现

[英]Allow variable to have any trait implementation

I have a program which interfaces with slightly different hardware.我有一个与略有不同的硬件接口的程序。 All hardware types support the same features which can be encapsulated in a trait.所有硬件类型都支持相同的功能,这些功能可以封装在特征中。

I would like to assign the hardware used based on an argument to the program.我想根据参数将使用的硬件分配给程序。

A minimal version of what I would try to achieve is the following我将尝试实现的最小版本如下

trait Hardware{
     ...
}

impl Hardware for HardwareTypeOne{
    ...
}
impl Hardware for HardwareTypeTwo{
    ...
}
fn do_stuff_with_hw(hw &mut impl Hardware){
    ...
}
fn main(){
    ...
    let hw = match args{
        arg_types::hw_1 => HardwareTypeOne,
        arg_types::hw_2 => HardwareTypeTwo,
    };
    hw.run_something();
    do_stuff_with_hw(&hw)
}

This of course won't work as the compiler will complain about not knowing the size of the hw variable at compile time.这当然不会起作用,因为编译器会抱怨在编译时不知道hw变量的大小。

I tried implementing this using boxing我尝试使用拳击来实现这个

Using if/else i was able to get this to work使用 if/else 我能够让它工作

let hw:Box<dyn Hardware>
if args == arg_types::hw_1{
    hw = Box::new(HardwareTypeOne);
}
else{
    hw = Box::new(HardwareTypeTwo);
}

But running:但是运行:

hw.run_somenthing()
do_stuff_with_hw(&hw)

then won't work since the type has changed.然后将无法工作,因为类型已更改。 And trying to "unbox" the variable will of course give the same error, complaining about the size not being known.并且尝试“拆箱”变量当然会给出相同的错误,抱怨大小未知。

How does one go about doing something like this in rust?一个 go 如何在 rust 中做这样的事情? I would like to avoid having to compile different versions of the software for different implementations.我想避免为不同的实现编译不同版本的软件。

This can work, with a few fixes:这可以工作,有一些修复:

trait Hardware {
    fn run_something(&self);
}

struct HardwareTypeOne;
struct HardwareTypeTwo;

impl Hardware for HardwareTypeOne {
    fn run_something(&self) {
        println!("run_something type one");
    }
}

impl Hardware for HardwareTypeTwo {
    fn run_something(&self) {
        println!("run_something type two");
    }
}

fn do_stuff_with_hw(_hw: &mut (impl Hardware + ?Sized)) {
}

fn main() {
    let mut hw: Box<dyn Hardware> = match true {
        true => Box::new(HardwareTypeOne),
        false => Box::new(HardwareTypeTwo),
    };
    
    hw.run_something();
    do_stuff_with_hw(&mut *hw);
}
  • hw in main() must be declared mut in order to obtain a mutable reference to the value in the box.必须将main()中的hw声明为mut以获得对框中值的可变引用。
  • You need to use the syntax &mut *hw to obtain a mutable reference to the value inside the box.您需要使用语法&mut *hw来获取对框内值的可变引用。
  • You need to relax the implicit Sized constraint on do_stuff_with_hw 's argument type by adding the ?Sized constraint;您需要通过添加?Sized约束来放宽对do_stuff_with_hw的参数类型的隐式Sized约束; this allows it to be invoked with a &mut dyn Hardware .这允许使用&mut dyn Hardware调用它。 (Alternatively, you can have the method take &mut dyn Hardware instead of &mut impl Hardware .) (或者,您可以让方法采用&mut dyn Hardware而不是&mut impl Hardware 。)

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

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