Идиоматический способ создания статичной итерируемой коллекции именованных структур в ржавчине - PullRequest
0 голосов
/ 05 марта 2019

Что такое идиоматический способ создания статической итерируемой коллекции именованных структур в ржавчине?У меня есть 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);
    }
}

Какой самый идиоматичный способ справиться с этой ситуацией в ржавчине?

1 Ответ

0 голосов
/ 07 марта 2019

Глядя на:

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);
    }
}

Я вижу Командный шаблон , пытающийся появиться, и 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();
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...