Изменены для 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);
}
Здесь я использую специальный признак, num::traits::NumCast
от num
обрешетки, которая реализуется для всех примитивных типов и обеспечивает статический метод, который преобразует эти типы из ничего, реализующего num::ToPrimitive
. num
Ящик также предоставляет функцию, num::cast()
, которая дает простой интерфейс для выполнения числовых операций.
Отметьте, что cast(x)
Option<T>
; он возвращает None
, если x
не может быть представлено в целевом типе. Я использую unwrap()
здесь, потому что в вашем случае, согласно вашему описанию, невозможность правильно преобразовать значение, скорее всего, является ошибкой программирования, поэтому выполнение задачи кажется более уместным. Также можно написать cast(x)
непосредственно:
if x >= S::zero() { num::cast(x) }
...
В этом случае check()
вернется None
не только тогда, когда ее аргумент является отрицательным, но если это невозможно преобразовать аргумент типа результата.
Это именно то, что я искал! – nodakai
К сожалению, больше нет указателя 'std :: num :: NumCast' или' ToPrimitive', и я не уверен, что они были заменены чем-либо. Вещи имеют довольно значительные изменения – Ponkadoodle
@Wallacoloo, действительно, большинство числовых признаков были удалены из 'std'. Некоторые из них, в том числе связанные с преобразованиями, были перенесены в ящик 'num'. Я скоро обновлю ответ. –