如何使用数字文字和数字中的整数特征? [英] How do I use number literals with the Integer trait from the num crate?

查看:108
本文介绍了如何使用数字文字和数字中的整数特征?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想实现一个函数来计算任何泛型类型的整数中的位数。这是我想出的代码:

  extern crate num; 
使用num :: Integer;

fn int_length< T:整数>(mut x:T) - > u8 {
如果x == 0 {
return 1;
}

let mut length = 0u8;
如果x < 0 {
长度+ = 1;
x = -x;
}

,而x> 0 {
x / = 10;
长度+ = 1;





fn main(){
println!({},int_length(45));
println!({},int_length(-45));
}

这里是编译器输出

 错误[E0308]:不匹配的类型
- > src / main.rs:5:13
|
5 |如果x == 0 {
| ^预期的类型参数,找到整数变量
|
= note:期望类型`T`
找到类型`{integer}`

错误[E0308]:不匹配类型
- > src / main.rs:10:12
|
10 |如果x < 0 {
| ^预期的类型参数,找到整数变量
|
= note:期望的类型`T`
找到类型`{integer}`

错误:不能应用一元运算符`-`来输入`T`
- - > src / main.rs:12:13
|
12 | x = -x;
| ^^

错误[E0308]:不匹配的类型
- > src / main.rs:15:15
|
15 |而x> 0 {
| ^预期的类型参数,找到整数变量
|
= note:期望类型`T`
找到类型`{integer}`

错误[E0368]:二进制赋值操作`/ =`不能应用于'T'类型`
- > src / main.rs:16:9
|
16 | x / = 10;
| ^不能在类型`T`上使用`/ =`

我明白问题来自我的使用的函数中的常量,但我不明白为什么 Integer 这些特征规范不能解决这个问题。



Integer 表示它实现了 PartialOrd 等特质,其中 Self (我假定它指的是整数)。通过使用也实现 Integer 特征的整数常量,不是定义的操作,编译器不应该没有错误地编译?



我尝试用 i32 后缀常量,但错误消息是相同的,用 _ i32

解决方案

p>


  1. 正如Shepmaster所说: 0 1 不能转换为执行整数的所有内容。改用 Zero :: zero One :: one code> 10 绝对不能转换为任何实现 Integer 的东西,你需要使用 NumCast 对于 a = a / b
  2. a / = b / code>,但是一个单独的特征 Integer 不需要。
  3. -x code>是一元操作,它不是整数的一部分,但需要 Neg 特征(因为它只是对签名类型有意义)。
  4. 请注意,您需要 Neg 上的限制,以确保它与 T



      extern crate num; 

    使用std :: ops :: Neg;
    使用num :: {Integer,NumCast};

    fn int_length< T>(mut x:T) - > u8
    其中T:整数+负值<输出= T> + NumCast
    {
    if x == T :: zero(){
    return 1;
    }

    let mut length = 0;
    如果x < T :: zero(){
    length + = 1;
    x = -x;
    }

    ,而x> T :: zero(){
    x = x / NumCast :: from(10).unwrap();
    长度+ = 1;





    fn main(){
    println!({},int_length(45));
    println!({},int_length(-45));
    }


    I wanted to implement a function computing the number of digits within any generic type of integer. Here is the code I came up with:

    extern crate num;
    use num::Integer;
    
    fn int_length<T: Integer>(mut x: T) -> u8 {
        if x == 0 {
            return 1;
        }
    
        let mut length = 0u8;
        if x < 0 {
            length += 1;
            x = -x;
        }
    
        while x > 0 {
            x /= 10;
            length += 1;
        }
    
        length
    }
    
    fn main() {
        println!("{}", int_length(45));
        println!("{}", int_length(-45));
    }
    

    And here is the compiler output

    error[E0308]: mismatched types
     --> src/main.rs:5:13
      |
    5 |     if x == 0 {
      |             ^ expected type parameter, found integral variable
      |
      = note: expected type `T`
                 found type `{integer}`
    
    error[E0308]: mismatched types
      --> src/main.rs:10:12
       |
    10 |     if x < 0 {
       |            ^ expected type parameter, found integral variable
       |
       = note: expected type `T`
                  found type `{integer}`
    
    error: cannot apply unary operator `-` to type `T`
      --> src/main.rs:12:13
       |
    12 |         x = -x;
       |             ^^
    
    error[E0308]: mismatched types
      --> src/main.rs:15:15
       |
    15 |     while x > 0 {
       |               ^ expected type parameter, found integral variable
       |
       = note: expected type `T`
                  found type `{integer}`
    
    error[E0368]: binary assignment operation `/=` cannot be applied to type `T`
      --> src/main.rs:16:9
       |
    16 |         x /= 10;
       |         ^ cannot use `/=` on type `T`
    

    I understand that the problem comes from my use of constants within the function, but I don't understand why the trait specification as Integer doesn't solve this.

    The documentation for Integer says it implements the PartialOrd, etc. traits with Self (which I assume refers to Integer). By using integer constants which also implement the Integer trait, aren't the operations defined, and shouldn't the compiler compile without errors?

    I tried suffixing my constants with i32, but the error message is the same, replacing _ with i32.

    解决方案

    Many things are going wrong here:

    1. As Shepmaster says: 0 and 1 cannot be converted to everything implementing Integer. Use Zero::zero and One::one instead.
    2. 10 can definitely not be converted to anything implementing Integer, you need to use NumCast for that
    3. a /= b is not sugar for a = a / b but an separate trait that Integer does not require.
    4. -x is an unary operation which is not part of Integer but requires the Neg trait (since it only makes sense for signed types).

    So here's an implementation. Note that you need a bound on Neg, to make sure that it results in the same type as T

    extern crate num;
    
    use std::ops::Neg;
    use num::{Integer, NumCast};
    
    fn int_length<T>(mut x: T) -> u8
        where T: Integer + Neg<Output = T> + NumCast
    {
        if x == T::zero() {
            return 1;
        }
    
        let mut length = 0;
        if x < T::zero() {
            length += 1;
            x = -x;
        }
    
        while x > T::zero() {
            x = x / NumCast::from(10).unwrap();
            length += 1;
        }
    
        length
    }
    
    fn main() {
        println!("{}", int_length(45));
        println!("{}", int_length(-45));
    }
    

    这篇关于如何使用数字文字和数字中的整数特征?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆