【问题标题】:How to cast generic types that I know to be integers?如何转换我知道是整数的泛型类型?
【发布时间】:2014-09-25 15:43:33
【问题描述】:

我想以通用方式检查 C API 的返回码,并且结果必须不包含 libc::c_int 等 C 类型。有什么方法可以写出类似的函数

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`

【问题讨论】:

    标签: casting rust parametric-polymorphism


    【解决方案1】:

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

    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&lt;T&gt;;如果x 不能在目标类型中表示,则返回None。我在这里使用unwrap() 是因为在您的情况下,根据您的描述,无法正确转换值可能是编程错误,因此任务失败感觉更合适。也可以直接写cast(x)

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

    在这种情况下,check() 将返回 None,不仅当它的参数为负数时,而且如果不能将参数转换为结果类型。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-06-30
      • 1970-01-01
      • 2020-11-09
      • 1970-01-01
      • 2017-03-11
      • 1970-01-01
      • 2014-09-19
      相关资源
      最近更新 更多