反射的惯用替代
Idiomatic alternative to reflection
我正在尝试 select 基于配置字符串的摘要算法(来自 rust-crypto)。例如,在 Python 或 JavaScript 中,我可能会使用反射来实现:
getattr(Digest, myAlgorithm)
...但是据我所知 Google,这不是 Rust 等语言的最佳实践(而且我没有找到有关如何完成的详细信息) .我最初的想法是使用模式匹配:
let mut digest = match myAlgorithm {
"sha256" => Sha256::new(),
...
};
但是,这是行不通的,因为虽然匹配的所有分支都实现了相同的特征,但它们最终是不同的类型。此外,假设有办法解决这个问题,在代码中手动枚举所有这些选项会很麻烦。
在 Rust 中执行此操作的正确方法是什么?
由于所有算法都实现了相同的特征 Digest
,它提供了您需要的一切,您可以将所有算法打包并将它们转换为通用的 Box<Digest>
:
let mut digest: Box<Digest> = match my_algorithm {
"sha256" => Box::new(Sha256::new()),
...
};
现在您不再知道类型是什么,但您仍然知道它是 Digest
。
python 和 javascript 在后台为您进行装箱(动态堆分配)。 Rust 对此类事情非常挑剔,因此需要您明确说明您的意思。
在 Rust 中进行反射以枚举范围内实现特征的所有类型会很有趣,但是这样的系统需要在 Rust 编译器和 Rust 社区的大脑中付出相当多的努力成员。不要指望很快。
我正在尝试 select 基于配置字符串的摘要算法(来自 rust-crypto)。例如,在 Python 或 JavaScript 中,我可能会使用反射来实现:
getattr(Digest, myAlgorithm)
...但是据我所知 Google,这不是 Rust 等语言的最佳实践(而且我没有找到有关如何完成的详细信息) .我最初的想法是使用模式匹配:
let mut digest = match myAlgorithm {
"sha256" => Sha256::new(),
...
};
但是,这是行不通的,因为虽然匹配的所有分支都实现了相同的特征,但它们最终是不同的类型。此外,假设有办法解决这个问题,在代码中手动枚举所有这些选项会很麻烦。
在 Rust 中执行此操作的正确方法是什么?
由于所有算法都实现了相同的特征 Digest
,它提供了您需要的一切,您可以将所有算法打包并将它们转换为通用的 Box<Digest>
:
let mut digest: Box<Digest> = match my_algorithm {
"sha256" => Box::new(Sha256::new()),
...
};
现在您不再知道类型是什么,但您仍然知道它是 Digest
。
python 和 javascript 在后台为您进行装箱(动态堆分配)。 Rust 对此类事情非常挑剔,因此需要您明确说明您的意思。
在 Rust 中进行反射以枚举范围内实现特征的所有类型会很有趣,但是这样的系统需要在 Rust 编译器和 Rust 社区的大脑中付出相当多的努力成员。不要指望很快。