如何定义可以返回给定整数类型的泛型函数?

时间:2019-10-13 13:32:12

标签: rust

我想定义一个函数,该函数可以返回在调用函数时指定其类型的数字。该函数需要一个缓冲区(Vec<u8>)并返回数字值,例如

let byte = buf_to_num<u8>(&buf);
let integer = buf_to_num<u32>(&buf);

缓冲区包含一个表示数字的ASCII字符串,例如b"827",其中每个字节都是一个数字的ASCII码。

这是我的无效代码:

  extern crate num;
  use num::Integer;
  use std::ops::{MulAssign, AddAssign};

  fn buf_to_num<T: Integer + MulAssign + AddAssign>(buf: &Vec::<u8>) -> T {
    let mut result : T;
    for byte in buf {
      result *= 10;
      result += (byte - b'0');
    }
    result
  } 

我在加法和乘法行(expected type T, found u32)上都得到了不匹配的类型错误。因此,我想我的问题是如何告诉类型系统T可以用文字10还是(byte - b'0')的结果来表示?

1 个答案:

答案 0 :(得分:2)

欢迎您不必指定您要用作泛型的每个操作。这很痛苦,但值得。

您有两个问题:

  1. result *= 10;,但没有相应的From<_>定义。这是因为,当您指定“ 10”时,编译器无法知道T代表的“ 10”是什么-它知道原始类型,以及通过实现From<_>定义的任何转换特质
  2. 您要混合两个操作-从字符向量到整数的强制转换以及您的操作。

我们需要为此做两个假设:

  • 我们将需要From<u32>,因此我们可以将数字限制为u32

  • 我们还将阐明您的逻辑并将每个u8转换为char,以便我们可以使用to_digit()那个转换为{{1} },然后再使用u32获得From<u32>

    T

您可以使自己相信其行为on the playground

通过将常数强制转换为use std::ops::{MulAssign, AddAssign}; fn parse_to_i<T: From<u32> + MulAssign + AddAssign>(buf: &[u8]) -> T { let mut buffer:T = (0 as u32).into(); for o in buf { buffer *= 10.into(); buffer += (*o as char).to_digit(10).unwrap_or(0).into(); } buffer } 来解决乘法问题,这使它受益于我们对T的u8的要求,并使rust编译器知道我们没有做傻事。

最后的更改是将From<u8>设置为默认值0。

让我知道这对您是否有意义(或者是否不可行),如果有问题,我很乐意进一步阐述:-)