我想以一种通用的方式判断C API的返回码,结果必须不包含C类型,比如libc::c_int
.有没有办法写出这样的函数
fn check<S: PartialOrd + std::num::Zero, T> (x: S) -> Option<T> {
if std::num::zero::<S>() <= x { Some(x as T) }
else { None }
}
当我确定S
和T
是check()
的所有用法的完整类型时?编译器拒绝我的代码
我想以一种通用的方式判断C API的返回码,结果必须不包含C类型,比如libc::c_int
.有没有办法写出这样的函数
fn check<S: PartialOrd + std::num::Zero, T> (x: S) -> Option<T> {
if std::num::zero::<S>() <= x { Some(x as T) }
else { None }
}
当我确定S
和T
是check()
的所有用法的完整类型时?编译器拒绝我的代码
将任意类型强制转换为任意类型是不可能的,而这正是(几乎)您要做的.在类型约束和转换操作中需要更加具体.
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);
}
在这里,我使用了一个特殊的特性,num
crate 中的num::NumCast
,它是为所有基本类型实现的,并提供了一个静态方法,可以将实现num::ToPrimitive
的任何类型转换为这些类型.num
crate 还提供了一个函数num::cast::cast()
,它提供了一个简单的界面来执行数字转换.
注意,cast(x)
返回Option<T>
;如果x
不能在目标类型中表示,则返回None
.我在这里使用unwrap()
是因为在您的情况下,根据您的描述,无法正确转换值很可能是编程错误,因此任务失败感觉更合适.也可以直接写cast(x)
:
if x >= S::zero() { num::cast(x) }
...
在这种情况下,check()
不仅在其参数为负时返回None
,而且在无法将参数转换为结果类型时也返回None
.
未被发送