nod*_*kai 5 casting rust parametric-polymorphism
我想以通用方式检查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 }
}
Run Code Online (Sandbox Code Playgroud)
当我确定这是S并且T是所有用法的整体类型check()?编译器拒绝我的代码抱怨error: non-scalar cast: `S` as `T`
针对Rust 1.x进行了更新
将任意类型转换为任意类型是不可能的,而这正是(几乎)你正在尝试做的事情.您需要在类型约束和转换操作中更具体.
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);
}
Run Code Online (Sandbox Code Playgroud)
在这里,我使用了一个特殊的特征,num::NumCast来自numcrate,它是为所有原始类型实现的,并提供了一个静态方法,可以从实现的任何东西转换为这些类型num::ToPrimitive.numcrate还提供了一个函数,num::cast::cast()它提供了一个简单的接口来执行数字转换.
注意cast(x)退货Option<T>; None如果x无法在目标类型中表示,则返回.我在unwrap()这里使用是因为在你的情况下,根据你的描述,无法正确转换值可能是一个编程错误,所以失败的任务感觉更合适.也可以cast(x)直接写:
if x >= S::zero() { num::cast(x) }
...
Run Code Online (Sandbox Code Playgroud)
在这种情况下,不仅在其参数为负时check()返回None,而且如果无法将参数转换为结果类型,则返回.
| 归档时间: |
|
| 查看次数: |
1607 次 |
| 最近记录: |