我有几个枚举。它们每个都有数字标签,可以转换为整数 (isize
)。我有一个他们都定义的特征。但该特征的实例不再可转换为整数,因为编译器无法证明所有实现实际上都是无参数枚举。
是否有任何特征表明类型是无参数枚举或者它可以转换为整数(以任何方式),我可以在需要获取数值的泛型中用作约束?
更具体地说,这是一个代码示例(also on play):
enum Foo {
a = 1,
b = 2,
c = 3,
}
enum Bar {
d = 4,
e = 5,
f = 6,
}
trait Process : std::marker::MarkerTrait {
fn process(v: isize) -> String;
}
impl Process for Foo {
fn process(v: isize) -> String { format!("foo{}", v) }
}
impl Process for Bar {
fn process(v: isize) -> String { format!("bar{}", v) }
}
// just for sake of argument; something more complex in reality, of course
fn extern_call(v: isize) -> isize { 2 * v + 211 }
fn process<T: Process>(v: T) -> String {
T::process(extern_call(v as isize))
}
fn main() {
println!("a: {}", process(Foo::a));
}
很明显问题出在process
,v as isize
编译失败
error: non-scalar cast:
T
asisize
所以我想做类似的事情
process<T: Process + scalar>
或
process<T: Process + ToPrimitive>
或者告诉编译器只允许可以转换为 isize 的类型,但我不知道那可能是什么。
最佳答案
向您的特征添加一个方法,将其强制为 isize
。然后编译器可以验证对象是否满足要求的标准:
enum Foo {
A = 1,
B = 2,
C = 3,
}
enum Bar {
D = 4,
E = 5,
F = 6,
}
trait Process: {
fn as_isize(self) -> isize;
fn process(v: isize) -> String;
}
impl Process for Foo {
fn as_isize(self) -> isize { self as isize }
fn process(v: isize) -> String { format!("foo{}", v) }
}
impl Process for Bar {
fn as_isize(self) -> isize { self as isize }
fn process(v: isize) -> String { format!("bar{}", v) }
}
// just for sake of argument; something more complex in reality, of course
fn extern_call(v: isize) -> isize { 2 * v + 211 }
fn process<T: Process>(v: T) -> String {
T::process(extern_call(v.as_isize()))
}
fn main() {
println!("a: {}", process(Foo::A));
}
仅供引用,此处不需要MarkerTrait
(并且不合惯用):
MarkerTrait is intended to be used as the supertrait for traits that don't have any methods
关于rust - 可转换为 isize 的枚举的特征,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29109354/