如何转换我知道是整数的泛型类型? [英] How to cast generic types that I know to be integers?

查看:24
本文介绍了如何转换我知道是整数的泛型类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想以通用方式检查 C API 的返回代码,并且结果必须不受 C 类型的影响,例如 libc::c_int.有没有什么方法可以写一个像

I want to check return codes of C APIs in a generic way and the result must be free from C types such as libc::c_int. Are there any ways to write a function like

fn check<S: PartialOrd + std::num::Zero, T> (x: S) -> Option<T> {
    if std::num::zero::<S>() <= x { Some(x as T) }
    else { None }
}

当我确定 STcheck() 的所有用法的整数类型时?编译器拒绝我的代码抱怨 error: non-scalar cast: `S` as `T`

when I'm sure that S and T are integral types for all usages of check()? The compiler rejects my code complaining error: non-scalar cast: `S` as `T`

推荐答案

将任意类型强制转换为任意类型是不可能的,而这(几乎)正是您想要做的.您需要在类型约束和转换操作方面更加具体.

It is impossible to cast arbitrary type to arbitrary type, and that's exactly (almost) what you're trying to do. You need to be more specific in type constraints and conversion operations.

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::NumCast 来自 num crate,它是为所有原始类型实现的,并提供了一个静态方法,可以将任何实现 num::ToPrimitive.num crate 还提供了一个函数,num::cast::cast(),它提供了一个简单的接口来执行数字转换.

Here I'm using a special trait, num::NumCast from num crate, which is implemented for all primitive types and provides a static method which converts to these types from anything which implements num::ToPrimitive. num crate also provides a function, num::cast::cast(), which gives a simple interface to perform numeric casts.

注意cast(x)返回Option;如果 x 不能在目标类型中表示,它返回 None.我在这里使用 unwrap() 是因为在你的情况下,根据你的描述,无法正确转换一个值可能是一个编程错误,所以失败的任务感觉更合适.也可以直接写cast(x):

Note that cast(x) returns Option<T>; it returns None if x can't be represented in the target type. I'm using unwrap() here because in your case, according to your description, inability to convert a value correctly is likely a programming error, so failing the task feels more appropriate. It is also possible to write cast(x) directly:

if x >= S::zero() { num::cast(x) }
...

在这种情况下,check() 将返回 None 不仅在其参数为负时,而且在无法将参数转换为结果类型时也会返回.

In this case check() will return None not only when its argument is negative, but also if it is impossible to convert the argument to the result type.

这篇关于如何转换我知道是整数的泛型类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆