Rust 如何在trait中实现将所有输入转换为usize而不使用'as usize`?
我有一个函数,根据Rust 如何在trait中实现将所有输入转换为usize而不使用'as usize`?,rust,traits,Rust,Traits,我有一个函数,根据usize输入返回: pub fn format_dhms(seconds: usize) -> String 如果输入为6000000: println!("{}", format_dhms(6000000)); 它返回: 69d10h40m 当输入是一个数字时,这是有效的,但是当我使用另一个固定类型函数的输出时,我需要使用作为usize。例如,如果我使用using方法的输出作为_secs()=u64或作为_nanos()=u128 当有人通过u128::MAX
usize
输入返回:
pub fn format_dhms(seconds: usize) -> String
如果输入为6000000
:
println!("{}", format_dhms(6000000));
它返回:
69d10h40m
当输入是一个数字时,这是有效的,但是当我使用另一个固定类型函数的输出时,我需要使用作为usize
。例如,如果我使用using方法的输出作为_secs()=u64
或作为_nanos()=u128
当有人通过u128::MAX
时,我会像处理usize
一样,将输入截断为最大可接受值
这就是我正在尝试的:()
#![允许(未使用)]
使用std::time::Instant;
fn格式(编号:T){
如果数字==0{
//println!(“{}”,编号)
}否则{
//println!(“{}>0”,数字)
}
}
fn main(){
让现在=瞬间::现在();
格式(now.appeased().as_nanos());//u128
格式(now.appeased().as_secs());//u64
}
但我得到的一些错误是:
error[E0277]:未满足特性绑定'usize:std::convert::From'
特性'std::convert::From'未为'usize'实现`
...
错误[E0369]:二进制操作“==”不能应用于类型“T”`
如果我删除
它可以工作,但我需要使用作为usize
format(now.elapsed().as_nanos() as usize);
是否有一种方法可以转换输入以防止使用as usize
,或者当输入只是一个没有定义类型的数字时如何实现相同的行为?使用特征,您可以“尝试”转换为其他类型。如果输入的数字太大,无法使用usize
,则会出现错误
fn foo(x:T)->使用{
x、 尝试进入()。展开()//如果
//x不适合
//变成一种习惯。
}
此外,这与类型转换的语义效果不同。因为这些将被截断,而这将不起作用
在这种情况下,真正的最佳实践是只对数字使用常规特征边界,而不是使用usize
,因为有些值不适合:
fn格式<
T:Sub+
Mul+
Div+
显示+
PartialEq+
从//等获取所需的所有操作。
>(编号:T){
如果number==T::from(false){/`false`将数字转换为0。
//println!(“{}”,编号)
}否则{
//println!(“{}>0”,数字)
}
}
然而,std
数字特征是相当简单的,所以我建议你看看。使用这个特征,你可以“尝试”转换成不同的类型。如果输入的数字太大,无法使用usize
,则会出现错误
fn foo(x:T)->使用{
x、 尝试进入()。展开()//如果
//x不适合
//变成一种习惯。
}
此外,这与类型转换的语义效果不同。因为这些将被截断,而这将不起作用
在这种情况下,真正的最佳实践是只对数字使用常规特征边界,而不是使用usize
,因为有些值不适合:
fn格式<
T:Sub+
Mul+
Div+
显示+
PartialEq+
从//等获取所需的所有操作。
>(编号:T){
如果number==T::from(false){/`false`将数字转换为0。
//println!(“{}”,编号)
}否则{
//println!(“{}>0”,数字)
}
}
然而,std
数字特征是相当简单的,所以我建议您看看。您可以使用std::mem::size\u of
来检查输入类型是否适合ausize
并在不适合时使用位操作来截断:
use std::convert::{ TryFrom, TryInto };
use std::fmt::Debug;
use std::ops::BitAnd;
use std::time::Instant;
fn format<T: TryInto<usize> + TryFrom<usize> + BitAnd<Output=T>> (number: T)
where <T as TryFrom<usize>>::Error: Debug,
<T as TryInto<usize>>::Error: Debug
{
let number: usize = if std::mem::size_of::<T>() <= std::mem::size_of::<usize>() {
number.try_into().unwrap()
} else {
(number & usize::MAX.try_into().unwrap()).try_into().unwrap()
};
if number == 0 {
//println!("{}", number)
} else {
//println!("{}> 0", number)
}
}
使用std::convert:{TryFrom,TryInto};
使用std::fmt::Debug;
使用std::ops::BitAnd;
使用std::time::Instant;
fn格式(编号:T)
其中::错误:调试,
::错误:调试
{
让number:usize=if std::mem::size_of:()您可以使用std::mem::size_of
检查输入类型是否适合usize
并在不适合时使用位操作截断:
use std::convert::{ TryFrom, TryInto };
use std::fmt::Debug;
use std::ops::BitAnd;
use std::time::Instant;
fn format<T: TryInto<usize> + TryFrom<usize> + BitAnd<Output=T>> (number: T)
where <T as TryFrom<usize>>::Error: Debug,
<T as TryInto<usize>>::Error: Debug
{
let number: usize = if std::mem::size_of::<T>() <= std::mem::size_of::<usize>() {
number.try_into().unwrap()
} else {
(number & usize::MAX.try_into().unwrap()).try_into().unwrap()
};
if number == 0 {
//println!("{}", number)
} else {
//println!("{}> 0", number)
}
}
使用std::convert:{TryFrom,TryInto};
使用std::fmt::Debug;
使用std::ops::BitAnd;
使用std::time::Instant;
fn格式(编号:T)
其中::错误:调试,
::错误:调试
{
让number:usize=if std::mem::size_of:()看起来您的问题可能由的答案回答。如果不是,请您的问题解释差异。否则,我们可以将此问题标记为已回答。为_nanos()=u128
-在usize
大到足以容纳u128
的地方,没有生锈的系统运行。当有人经过u128::MAX
时,您希望发生什么?看起来您的问题可能由的答案来回答。如果没有,请您的问题解释差异。否则,我们可以标记这一点问题已经得到了回答。as_nanos()=u128
-在usize
大到可以容纳u128
的地方,没有运行生锈的系统。当有人经过u128::MAX
时,你想发生什么?你不能用这些边界写数字==0这不符合OP的要求-“通过将输入截断为最大可接受值”同样,这个答案似乎同意它将是的副本。@Stargateur我用一个变通方法编辑了它,但是使用num traits可能更好。你不能用这些边界写number==0这不符合OP的要求--通过将输入截断为“最大接受值”,这个答案似乎也同意它将是的副本。@Stargateur我用一个变通方法编辑了它,但是使用num traits可能更好。…(number:T)where::Error:Debug,::Error:Debug