How to cast generic types that I know to be integers?

烈酒焚心 提交于 2019-12-17 14:04:12

问题


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 }
}

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`


回答1:


Updated for Rust 1.x

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);
}

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.

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) }
...

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.



来源:https://stackoverflow.com/questions/26042703/how-to-cast-generic-types-that-i-know-to-be-integers

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!