我有一个类型,可以用f32表示,没有NaN、无穷大或负值,有一个最大值,一个普通的例子是人的身高(以米为单位),所以我用新的类型模式来表示它:
struct Height(f32);
impl TryFrom<f32> for Height {
type Error = &'static str;
fn try_from(value: f32) -> Result<Self, Self::Error> {
if value.is_infinite() || value.is_sign_negative() || value > 3. {
return Err("value was infinite");
}
Ok(Height(value))
}
}
我不喜欢的是当我必须处理一个数组时,因为它应该声明为
let vec = vec![Height::try_from(3.).unwrap(), Height::try_from(2.).unwrap()];
添加了很多样板文件。而且当我需要将它传递给一个接受&[f32]的函数时,转换起来有点麻烦。
处理这种情况的惯用方法是什么?
编辑:如果将300.改为3.,因为在示例中,我指的是人的身高,单位是米。
2条答案
按热度按时间5fjcxozz1#
也许一个宏要调用
Height::try_from(x).unwrap()
?比如
h!(3.0)
对于需要&[f32]的函数,要安全地从[Height] -〉[f32]进行转换,你必须使用Height中的f32来构造一个新的切片,这是O(n)的,所以不要太快。
一个更好的问题是为什么函数想要&[f32],你能改变它吗?
yeotifhr2#
最直接、最惯用的方法是使用迭代器和
map
:请参阅Rust Playground中的完整工作示例:https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=61a42b0a86c64f4a75bf4094da88b301
您也可以使用
macro_rules
来实现这一点,但这是一种过度使用。