pub fn trait_object_to_enum()
Expand description
§当不能实现 trait 对象当时候该如何?
- 将其转化为 Enum
trait 对象代码:
trait KnobControl {
fn set_position(&mut self, value: f64);
fn get_value(&self) -> f64;
}
struct LinearKnob {
position: f64,
}
struct LogarithmicKnob {
position: f64,
}
impl KnobControl for LinearKnob {
fn set_position(&mut self, value: f64) {
self.position = value;
}
fn get_value(&self) -> f64 {
self.position
}
}
impl KnobControl for LogarithmicKnob {
fn set_position(&mut self, value: f64) {
self.position = value;
}
fn get_value(&self) -> f64 {
(self.position + 1.).log2()
}
}
fn main() {
let v: Vec<Box<dyn KnobControl>> = vec![
//set the knobs
];
//use the knobs
}
转为 enum:
enum Knob {
Linear(LinearKnob),
Logarithmic(LogarithmicKnob),
}
impl KnobControl for Knob {
fn set_position(&mut self, value: f64) {
match self {
Knob::Linear(inner_knob) => inner_knob.set_position(value),
Knob::Logarithmic(inner_knob) => inner_knob.set_position(value),
}
}
fn get_value(&self) -> f64 {
match self {
Knob::Linear(inner_knob) => inner_knob.get_value(),
Knob::Logarithmic(inner_knob) => inner_knob.get_value(),
}
}
}
当 trait 不满足对象安全规则的时候,也可以用 Enum 代替。
#![allow(unused)]
use core::ops::Add;
trait KnobControl<T: Add + Add<Output = T> + Copy> {
fn set_position(&mut self, value: T);
fn get_value(&self, p: T) -> T;
}
struct LinearKnob<T: Add+ Add<Output = T> + Copy> {
position: T,
}
struct LogarithmicKnob<T: Add+ Add<Output = T> + Copy> {
position: T,
}
impl<T: Add+ Add<Output = T> + Copy> KnobControl<T> for LinearKnob<T> {
fn set_position(&mut self, value: T) {
self.position = value;
}
fn get_value(&self, p: T) -> T {
self.position + p
}
}
impl<T: Add+ Add<Output = T> + Copy> KnobControl<T> for LogarithmicKnob<T> {
fn set_position(&mut self, value: T) {
self.position = value;
}
fn get_value(&self, p: T) -> T {
(self.position + p)
}
}
fn main() {
enum Knob<T: Add+ Add<Output = T> + Copy> {
Linear(LinearKnob<T>),
Logarithmic(LogarithmicKnob<T>),
}
impl<T: Add+ Add<Output = T> + Copy> KnobControl<T> for Knob<T> {
fn set_position(&mut self, value: T) {
match self {
Knob::Linear(inner_knob) => inner_knob.set_position(value),
Knob::Logarithmic(inner_knob) => inner_knob.set_position(value),
}
}
fn get_value(&self, p: T) -> T {
match self {
Knob::Linear(inner_knob) => inner_knob.get_value(p),
Knob::Logarithmic(inner_knob) => inner_knob.get_value(p),
}
}
}
}
- 利用 “魔法” ,相当于加一层代理 : 参考:https://github.com/dtolnay/erased-serde/blob/master/explanation/main.rs