在rust中创建静态可迭代命名结构集合的惯用方法

问题描述 投票:2回答:1

在rust中创建静态可迭代命名结构集合的惯用方法是什么?我有一个结构的n实例,其中n在编译时是已知的并且小于20.我希望能够遍历所有条目,并且还能够通过名称而不是索引来引用每个条目。所有数据在编译时都是已知的。

我可以使用数组或枚举,以及手工编写的常量,将标签映射到索引;但这看起来很挑剔。


fn common_behaviour(x : f64) {
   print!("{}", x);
}

const ADD : usize = 0;
const SUBTRACT : usize = 1;


fn main () {
    let mut foos : [f64; 2] = [0.0; 2];
    foos[ADD] = 4.0;
    foos[SUBTRACT] = 2.0;

    for foo in &foos {
       common_behaviour(*foo);
    }
    foos[ADD] += 1.0;
    foos[SUBTRACT] -= 1.0;
}

或者,我可以只支付性能成本并使用HashMap,因为散列开销可能实际上并不重要,但这似乎也不是最理想的。

也许,我可以重构我的代码来使用函数指针而不是特殊情况下包装不同的特殊情况。

fn common_behaviour(x : f64) {
   print!("{}", x);
}

fn add(x : f64) -> f64 {
    x + 1.0
}

fn subtract(x : f64) -> f64 {
    x - 1.0
}

struct Foo {
   data : f64,
   special : fn(f64) -> f64
}

impl Foo {
    fn new(data : f64, special : fn(f64) -> f64) -> Foo {
        Foo{data, special}
    }
}

fn main() {
    let mut foos = [Foo::new(4.0, add), Foo::new(2.0, subtract)];

    for foo in &mut foos {
       common_behaviour(foo.data);
       foo.data = (foo.special)(foo.data);
    }
}

在锈病中处理这种情况的最惯用的方法是什么?

data-structures rust
1个回答
1
投票

看着:

fn main() {
    let mut foos = [Foo::new(4.0, add), Foo::new(2.0, subtract)];

    for foo in &mut foos {
       common_behaviour(foo.data);
       foo.data = (foo.special)(foo.data);
    }
}

我看到一个Command Pattern正在努力出现,而Rust非常善于表达这种模式,感谢enum

enum Foo {
    Add(f64),
    Sub(f64),
}

impl Foo {
    fn apply(&mut self) {
        match self {
            Foo::Add(x) => {
                Self::common(*x);
                *x += 1.0;
            },
            Foo::Sub(x) => {
                Self::common(*x);
                *x -= 1.0;
            },
        }
    }

    fn common(x: f64) {
        print!("{}", x);
    }
}

你的例子变成了:

fn main() {
    let mut foos = [Foo::Add(4.0), Foo::Sub(2.0)];

    for foo in &mut foos {
       foo.apply();
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.