2015-05-27 95 views
6

我想根據配置字符串選擇一個摘要算法(來自rust-crypto)。在Python或JavaScript,比如說,我可能會使用反射來得到這個:反射的習慣性替代

getattr(Digest, myAlgorithm) 

...但是從我已經能夠谷歌,這不是一個語言,如最佳實踐Rust(加上我沒有找到關於如何完成的細節)。我最初的想法是使用模式匹配:

let mut digest = match myAlgorithm { 
    "sha256" => Sha256::new(), 
    ... 
}; 

然而,這並不因爲工作,而本場比賽的所有分支實現相同的特質,他們最終不同的類型。此外,假設有一種解決方法,手動枚舉代碼中的所有這些選項是很麻煩的。

什麼是在Rust中做到這一點的正確方法?

+0

你知道魯斯特性嗎?它們用於爲多個實現指定一個通用接口。 –

回答

7

因爲所有的算法實現相同的特質Digest,它提供了你需要的一切,你可以框所有的算法,並將其轉換爲一個共同的Box<Digest>

let mut digest: Box<Digest> = match my_algorithm { 
    "sha256" => Box::new(Sha256::new()), 
    ... 
}; 

現在你不知道了什麼類型是,但你仍然知道這是一個Digest

python和javascript在後臺爲你做了裝箱(動態堆分配)。 Rust對這樣的事情非常挑剔,因此需要你明確地陳述你的意思。

Rust中的反射能夠枚舉實現特徵的範圍中的所有類型,但這樣的系統在鏽蝕編譯器和鏽蝕社區成員的大腦中需要相當多的努力。不要期待它很快。

+0

謝謝:那麼特質有點像Haskell類型類?無論如何,這會繞過類型檢查問題,但現在當我嘗試使用這個時,我沒有爲類型Box實現'trait \'crypto :: digest :: Digest \' \'' – Xophmeister

+0

呵呵......這很奇怪...作爲一種破解,你可以嘗試通過使用'&* digest'來獲得對內部對象的引用。但是,如果不知道你所嘗試的更多細節,我無法提供幫助。 –

+0

@Xophmeister'Digest'的定義是什麼?代碼ker只有在特質[對象安全]時纔會有效(https://huonw.github.io/blog/2015/01/object-safety/)。 –