rust - Grouping structs with enums -
in rust, how should 1 go grouping related structs function signature can accept multiple different types while refering concrete type inside method body?
the following example contrived simplicity:
enum command { increment {quantity: u32}, decrement {quantity: u32}, } fn process_command(command: command) { match command { command::increment => increase(command), command::decrement => decrease(command), }; } fn increase(increment: command::increment) { println!("increasing by: {}.", increment.quantity); } fn decrease(decrement: command::decrement) { println!("decreasing by: {}.", decrement.quantity); } fn main() { let input = "add"; let quantity = 4; let command: command = match input { "add" => command::increment { quantity: quantity }, "subtract" => command::decrement { quantity: quantity }, _ => unreachable!(), }; process_command(command); }
compiling results in following 2 errors:
src/main.rs:13:24: 13:42 error: found value name used type: defvariant(defid { krate: 0, node: 4 }, defid { krate: 0, node: 5 }, true) [e0248] src/main.rs:13 fn increase(increment: command::increment) { ^~~~~~~~~~~~~~~~~~ src/main.rs:17:24: 17:42 error: found value name used type: defvariant(defid { krate: 0, node: 4 }, defid { krate: 0, node: 8 }, true) [e0248] src/main.rs:17 fn decrease(decrement: command::decrement) { ^~~~~~~~~~~~~~~~~~ error: aborting due 2 previous errors
if declare structs seperately, , wrap structs within tuple struct (correct terminology?) each within enum expected result, verbosity , similar type names on place suspect i've misunderstood someting:
struct increment { quantity: u32, } struct decrement { quantity: u32, } enum command { increment(increment), decrement(decrement), } fn process_command(command: command) { match command { command::increment(increment) => increase(increment), command::decrement(decrement) => decrease(decrement), }; } fn increase(increment: increment) { println!("increasing by: {}.", increment.quantity); } fn decrease(decrement: decrement) { println!("decreasing by: {}.", decrement.quantity); } fn main() { let input = "add"; let quantity = 4; let command: command = match input { "add" => command::increment(increment { quantity: quantity }), "subtract" => command::decrement(decrement { quantity: quantity }), _ => unreachable!(), }; process_command(command); }
running outputs:
increasing by: 4.
is wrapping struct within enum type (terminology?) sharing same name best solution? command::increment(increment { quantity: 7 })
yes, best along line of implementation. enum 1 type only; variants purely that—variants, not types.
another alternative use trait , generics:
struct increment { quantity: u32, } struct decrement { quantity: u32, } trait command { fn process(self); } impl command increment { fn process(self) { println!("increasing {}", self.quantity); } } impl command decrement { fn process(self) { println!("decreasing {}", self.quantity); } }
of course, it’s not direct parallel; if want store command
of potentially differing types you’ll need change process
take self: box<self>
or &self
, , you’ll need work either box<command>
or &command
, it’s way of doing things may suit requirements. , far definitions concerned, it’s purer.
Comments
Post a Comment