将任意类型转换为任意类型是不可能的,而这正是(几乎)您想要做的。您需要在类型约束和转换操作方面更加具体。
extern crate num;
use num::{Zero, NumCast};
fn check<S: PartialOrd + Zero + NumCast, T: NumCast>(x: S) -> Option<T> {
if x >= S::zero() { Some(num::cast(x).unwrap()) }
else { None }
}
fn main() {
let x: i8 = 10;
let y: Option<i32> = check(x);
println!("{:?}", y);
let x: i8 = -10;
let y: Option<i32> = check(x);
println!("{:?}", y);
}
在这里,我使用了一个特殊的 trait,num::NumCast
来自num
crate,它为所有原始类型实现,并提供了一个静态方法,该方法可以从任何实现num::ToPrimitive
. num
crate 还提供了一个函数 ,num::cast::cast()
它提供了一个简单的接口来执行数字转换。
请注意,cast(x)
返回Option<T>
; None
如果x
无法在目标类型中表示,则返回。我在unwrap()
这里使用是因为在您的情况下,根据您的描述,无法正确转换值可能是编程错误,因此任务失败感觉更合适。也可以cast(x)
直接写:
if x >= S::zero() { num::cast(x) }
...
在这种情况下,不仅check()
会在其参数为负数时返回None
,而且在无法将参数转换为结果类型时也会返回。