我正在使用一种设计模式,其中数字由类型表示,如previous question中所述。这对于我通常的用例来说效果很好,但是我希望能够实现一些测试代码,该代码能够生成具有数字类型的实例(并知道相应的数字)。
对于与固定编号相对应的固定类型,我可以执行以下操作:
use std::marker::PhantomData;
trait U32Const {
const VAL: u32;
}
struct U32Const10;
impl U32Const for U32Const10 {
const VAL: u32 = 10;
}
trait MyTrait {
fn do_something(&self, val: u32) -> u32;
}
struct MyType<X: U32Const> {
marker: PhantomData<X>,
}
impl<X: U32Const> MyType<X> {
fn new() -> MyType<X> {
MyType::<X> {
marker: PhantomData,
}
}
}
impl<X: U32Const> MyTrait for MyType<X> {
fn do_something(&self, val: u32) -> u32 {
val * X::VAL
}
}
fn get_instance() -> impl MyTrait {
MyType::<U32Const10>::new()
}
fn main() {
let a = get_instance();
println!("{}", a.do_something(4));
}
我想要能做的就是让最后的get_instance()
函数接受一个变量并返回不同的实例:
// The detail of the function is not important;
// I don't care about what it really looks like.
fn get_instance(val) -> Something {
// ??? returns an instance of MyType::<U32ConstN>::new() where N is set by val
}
由于这纯粹是出于内部测试目的,我很高兴拥有低级别的争用和不安全的代码。
起初我想枚举所有可能的值,但后来我遇到了具有不同类型的匹配分支的问题,这导致特征对象,我想知道是否存在更整洁的解决方案。