我想做一个程序,使用命令行参数来选择使用的结构。类似于这样:
trait Animal {
fn sound(&self) -> &str;
}
struct Dog {}
impl Animal for Dog {
fn sound(&self) -> &str {
"Woof!"
}
}
struct Cat {}
impl Animal for Cat {
fn sound(&self) -> &str {
"Miau!"
}
}
trait Place {
fn name(&self) -> &str;
}
struct Museum {}
impl Place for Museum {
fn name(&self) -> &str {
"museum"
}
}
struct Hotel{}
impl Place for Hotel {
fn name(&self) -> &str {
"hotel"
}
}
fn get_animal(animal: &str) -> Box<dyn Animal> {
match animal {
"dog" => Box::new(Dog{}),
"cat" => Box::new(Cat{}),
_ => todo!()
}
}
fn get_place(place: &str) -> Box<dyn Place> {
match place {
"museum" => Box::new(Museum{}),
"hotel" => Box::new(Hotel{}),
_ => todo!()
}
}
fn sentence(animal: Box<dyn Animal>, place: Box<dyn Place>) {
println!("{} We are at {}.", animal.sound(), place.name());
}
fn main() {
let args: Vec<String> = env::args().collect();
let animal = get_animal(&args[1]);
let place = get_place(&args[2]);
sentence(animal, place);
}
字符串
然而,我使用的traits不是对象安全的,所以我不能使用dyn
。现在我只是对每个组合使用match
:
match (animal, place) {
("dog", "museum") => sentence(Dog{}, Museum{}),
("dog", "hotel") => sentence(Dog{}, Hotel{}),
("cat", "museum") => sentence(Cat{}, Museum{}),
("cat", "hotel") => sentence(Cat{}, Hotel{}),
}
型
然而,我将在程序中添加更多的结构体,所以这是不可伸缩的。有没有什么可伸缩的方法来解决这个问题?有没有可能创建一个宏来生成match
,这样我就不必手动编写它,或者有没有更好的解决方案?
我使用的特征是:
- PrimeField:https://docs.rs/ark-ff/latest/ark_ff/fields/trait.PrimeField.html
- 约束合成器:https://docs.rs/ark-relations/latest/ark_relations/r1cs/trait.ConstraintSynthesizer.html
- PolynomialCommitment:https://docs.rs/ark-poly-commit/latest/ark_poly_commit/trait.PolynomialCommitment.html
修改traits使其成为对象安全的可能不是一个好主意,原因有两个:
1.这些库执行复杂的数学算法,不容易理解。
1.该程序用于对库进行基准测试。也许修改特性可以改变库的性能。
1条答案
按热度按时间dphi5xsq1#
基本上有两个原因可以解释为什么trait不是对象安全的:
self
参数)。如果你需要调用一个这样的trait方法,那么你将需要使用
match
,就像你正在做的(*)一样。这可以通过使用crate(例如enum_dispatch
)来更加符合人体工程学。如果你需要调用的方法都是对象安全的,你可以创建一个 Package 器trait,它只包含对象安全的方法:
字符串
Playground的
(*)如果你需要访问有限数量的泛型方法,你仍然可以制作一个 Package trait,但是你需要为你计划使用的类型提供非泛型版本的泛型方法:用途:
型
Playground的