我想寫為定義的函式都浮點數和整數。
對于整數,我想使用saturating_add. 對于浮點數,沒有 saturating_add 函式,但常規 add 是飽和的(infinity_value positive_value = infinity_value)。
我就喜歡寫的是
fn sat_add<T: num_traits::Num>(x: T, o: T) -> T {
if implements(x, num_traits::ops::saturating::SaturatingAdd)
x.saturating_add(o) // Saturating addition, if available
else
x o // Fallback: regular addition
}
請注意, T 是靜態的,我希望它由編譯器行內。所以它更像是一種模式匹配(特征存在與否)而不是面向物件的編程。
(請注意,我目前正在使用宏為各種標準型別實作一種或另一種,但這僅涵蓋基本情況,通用的東西比列舉已知資料型別更好。)
uj5u.com熱心網友回復:
您可以定義一個特征并為所需的型別實作它:
pub trait MyAdd {
fn my_add(self, o: Self) -> Self;
}
macro_rules! my_add_int {
($($t:ty), ) => {$(
impl MyAdd for $t {
fn my_add(self, o:Self) -> Self {
<$t>::saturating_add(self, o)
}
}
)*}
}
macro_rules! my_add_float {
($($t:ty), ) => {$(
impl MyAdd for $t {
fn my_add(self, o:Self) -> Self {
self o
}
}
)*}
}
my_add_int!(i8, u8, i16, u16, i32, u32, i64, u64, isize, usize);
my_add_float!(f32, f64);
操場
uj5u.com熱心網友回復:
在當前的 Rust 中無法按照您希望的方式執行此操作,因為它需要專業化。
通過專業化(每晚可用),您的功能可以這樣實作:
#![feature(specialization)]
use num_traits;
use std::ops::Add;
// A helper trait to implement `saturating_add`
pub trait SaturatingAdd {
fn add(self, rhs: Self) -> Self;
}
impl<T: Add<Output = T>> SaturatingAdd for T {
// the fallback implementation, defined for anything that implements
// `T T`, is marked "default"
default fn add(self: T, rhs: T) -> T {
self rhs
}
}
impl<T: num_traits::ops::saturating::SaturatingAdd> SaturatingAdd for T {
// specialized implementation for types that define `saturating_add()`
fn add(self: T, rhs: T) -> T {
self.saturating_add(&rhs)
}
}
// With the trait in place, the implementation of the function
// boils down to invoking the trait's only method.
pub fn saturating_add<T: SaturatingAdd>(a: T, b: T) -> T {
a.add(b)
}
操場
不幸的是,它需要完整的specialization功能,它不適用于更普通的min_specialization. 換句話說,不要指望這會很快成為穩定版的一部分。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/363824.html
上一篇:二叉搜索樹,中序橫向回傳泛型陣列
