你需要或者盒或使用引用,作为“特质对象”可以只在指针后面工作。
下面是一个非常简化的代码版本。您必须实现相同的特质三种不同的结构(摘要)
struct Sha256;
struct Sha384;
struct Sha512;
trait Digest {}
impl Digest for Sha256 {}
impl Digest for Sha384 {}
impl Digest for Sha512 {}
struct HMac<D: Digest> { d: D }
fn main() {
let a = 1;
// what you're trying to do
// (does not work, Sha256, Sha384 and Sha512 are different types)
//let _ = match a {
// 1 => Sha256,
// 2 => Sha384,
// 3 => Sha512,
// _ => unreachable!()
//};
}
注意的是,在现实情况下,不仅所有ShaXXX类型是类型系统不同,它们具有不同的内存布局以及(比较Engine256State例如Engine512State),所以这排除了不安全的技巧transmute。
所以,说,你可以用盒子或引用(但你必须在比赛前预先创建一个具体的例子,如果你想使用的引用):
fn main() {
let a = 1;
let _ : Box<Digest> = match a {
1 => Box::new(Sha256),
2 => Box::new(Sha384),
3 => Box::new(Sha512),
_ => unreachable!()
};
// to use references we need a pre-existing instance of all ShaXXX
let (sha256, sha384, sha512) = (Sha256, Sha384, Sha512);
let _ : &Digest = match a {
1 => &sha256, //... otherwise the reference wouldn't outlive the match
2 => &sha384,
3 => &sha512,
_ => unreachable!()
};
}
。请注意,Box
做相当于大多数垃圾收集语言在您想通过其界面使用对象时为您提供的内容。有些内存是为具体对象动态分配的,但只能真正允许传递一个指向内存的指针。
在你的情况(但我没有测试过下面的代码),你应该能够做到:
//HMac implements a Mac trait, so we can return a Box<Mac>
// (I'm assuming you only want to use HMac through its Mac trait)
fn create_hmac<'a, D: Digest>(digest: D, some_str: &'a str) -> Box<Mac + 'a> {
Box::new(Hmac::new(digest, some_str.to_string().as_bytes()))
}
,并用它作为:
let mut hmac: Box<Mac> = match my_type {
MyType::MyType1 => create_hmac(Sha256::new(), some_str),
MyType::MyType2 => create_hmac(Sha384::new(), some_str),
MyType::MyType3 => create_hmac(Sha512::new(), some_str),
_ => unreachable!()
};
我一定是盲目的,因为我没有看到任何'Box'有 – 2015-02-09 06:36:56
请创建一个最小的编译例子 – 2015-02-09 07:44:23
@JorgeIsraelPeña,没有盒子在那里。但Box可以用来使它工作。但我不想用它。 – 2015-02-09 08:00:19