你需要或者盒或使用引用,作爲「特質對象」可以只在指針後面工作。
下面是一個非常簡化的代碼版本。您必須實現相同的特質三種不同的結構(摘要)
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