使用枚举对结构进行分组
Grouping structs with enums
在 Rust 中,应该如何对相关结构进行分组,以便函数签名可以在引用方法体内的具体类型时接受多种不同类型?
为简单起见,设计了以下示例:
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);
}
编译出现以下两个错误:
src/main.rs:13:24: 13:42 error: found value name used as a 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 as a 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 to 2 previous errors
如果我单独声明结构,并将结构包装在一个元组结构(正确的术语?)中,每个结构都在枚举中,那么我会得到预期的结果,但我怀疑到处都是冗长和相似的类型名称我误解了一些事情:
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);
}
运行 输出:
Increasing by: 4.
将结构包装在一个枚举类型(术语?)中并共享相同的名称真的是最好的解决方案吗? Command::Increment(Increment { quantity: 7 })
是的,这是您将在这条实施线上获得的最佳结果。枚举只是一种类型;它的变体纯粹是变体,而不是类型。
另一种选择是使用特征和泛型:
struct Increment {
quantity: u32,
}
struct Decrement {
quantity: u32,
}
trait Command {
fn process(self);
}
impl Command for Increment {
fn process(self) {
println!("Increasing by {}", self.quantity);
}
}
impl Command for Decrement {
fn process(self) {
println!("Decreasing by {}", self.quantity);
}
}
当然不是直接平行;如果您想存储可能不同类型的 command
,您需要将 process
更改为 self: Box<Self>
或 &self
,并且您需要使用 Box<Command>
或 &Command
,但这是另一种可能适合您要求的处理方式。而且就定义而言,它更纯粹。
关于这个,我不确定我是否真的理解你的问题
enum Command {
Increment (u32),
Decrement (u32),
}
fn process_command(command: Command) {
match command {
Command::Increment(quantity) => increase(quantity),
Command::Decrement(quantity) => decrease(quantity),
};
}
fn increase(quantity: u32) {
println!("Increasing by: {}.", quantity);
}
fn decrease(quantity: u32) {
println!("Decreasing by: {}.", quantity);
}
fn main() {
let input = "Add";
let quantity = 4;
let command: Command = match input {
"Add" => Command::Increment (quantity),
"Subtract" => Command::Decrement (quantity),
_ => unreachable!(),
};
process_command(command);
}
我可能误解了你的简单示例,但请记住你可以直接在枚举上实现方法:
enum Command {
Increment {quantity: u32},
Decrement {quantity: u32},
}
impl Command {
fn process(self) {
match self {
Command::Increment { quantity } => {
println!("Increasing by: {}.", quantity)
},
Command::Decrement { quantity } => {
println!("Decreasing by: {}.", 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!(),
};
command.process();
}
我正好喜欢这个版本,因为它消除了process_command(command)
的冗余。
在 Rust 中,应该如何对相关结构进行分组,以便函数签名可以在引用方法体内的具体类型时接受多种不同类型?
为简单起见,设计了以下示例:
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);
}
编译出现以下两个错误:
src/main.rs:13:24: 13:42 error: found value name used as a 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 as a 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 to 2 previous errors
如果我单独声明结构,并将结构包装在一个元组结构(正确的术语?)中,每个结构都在枚举中,那么我会得到预期的结果,但我怀疑到处都是冗长和相似的类型名称我误解了一些事情:
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);
}
运行 输出:
Increasing by: 4.
将结构包装在一个枚举类型(术语?)中并共享相同的名称真的是最好的解决方案吗? Command::Increment(Increment { quantity: 7 })
是的,这是您将在这条实施线上获得的最佳结果。枚举只是一种类型;它的变体纯粹是变体,而不是类型。
另一种选择是使用特征和泛型:
struct Increment {
quantity: u32,
}
struct Decrement {
quantity: u32,
}
trait Command {
fn process(self);
}
impl Command for Increment {
fn process(self) {
println!("Increasing by {}", self.quantity);
}
}
impl Command for Decrement {
fn process(self) {
println!("Decreasing by {}", self.quantity);
}
}
当然不是直接平行;如果您想存储可能不同类型的 command
,您需要将 process
更改为 self: Box<Self>
或 &self
,并且您需要使用 Box<Command>
或 &Command
,但这是另一种可能适合您要求的处理方式。而且就定义而言,它更纯粹。
关于这个,我不确定我是否真的理解你的问题
enum Command {
Increment (u32),
Decrement (u32),
}
fn process_command(command: Command) {
match command {
Command::Increment(quantity) => increase(quantity),
Command::Decrement(quantity) => decrease(quantity),
};
}
fn increase(quantity: u32) {
println!("Increasing by: {}.", quantity);
}
fn decrease(quantity: u32) {
println!("Decreasing by: {}.", quantity);
}
fn main() {
let input = "Add";
let quantity = 4;
let command: Command = match input {
"Add" => Command::Increment (quantity),
"Subtract" => Command::Decrement (quantity),
_ => unreachable!(),
};
process_command(command);
}
我可能误解了你的简单示例,但请记住你可以直接在枚举上实现方法:
enum Command {
Increment {quantity: u32},
Decrement {quantity: u32},
}
impl Command {
fn process(self) {
match self {
Command::Increment { quantity } => {
println!("Increasing by: {}.", quantity)
},
Command::Decrement { quantity } => {
println!("Decreasing by: {}.", 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!(),
};
command.process();
}
我正好喜欢这个版本,因为它消除了process_command(command)
的冗余。