Cannot create a generic function that uses a literal zero

前端 未结 1 1592
醉梦人生
醉梦人生 2020-12-07 04:40

I am trying to write a Rust function that is similar to the built-in Range, but I want something that will return only X numbers, and return it as a list, which

相关标签:
1条回答
  • 2020-12-07 05:30

    The problem is 0. I'm unclear on the exact rules right now, but let's be general: 0 is of some specific integer type, which may or may not be the same thing as whatever T is. Thus, the compiler can't work out what the type parameter to range is supposed to be.

    You can resolve this by using Zero::zero:

    fn positions<T: Integer>(start: T, step: T, len: T) -> Vec<T> {
        (T::zero()..len).map(|i| start + step * i).collect()
    }
    

    This gives the compiler enough leeway to infer that the two arguments to range are of the same type. However, that's still not enough to use Range as an iterator:

    error: no method named `map` found for type `std::ops::Range<T>` in the current scope
     --> src/main.rs:8:22
      |
    8 |     (T::zero()..len).map(|i| start + step * i).collect()
      |                      ^^^
      |
      = note: the method `map` exists but the following trait bounds were not satisfied: `T : std::iter::Step`, `&'a T : std::ops::Add`, `std::ops::Range<T> : std::iter::Iterator`
    

    Unfortunately, as of Rust 1.17, the Step trait is unstable, so there's currently no good way to solve this problem using stable Rust.

    Using unstable Rust, you can require implementations of Step:

    #![feature(step_trait)]
    
    extern crate num;
    
    use num::Integer;
    
    fn positions<T>(start: T, step: T, len: T) -> Vec<T>
        where T: Integer + std::iter::Step + Copy,
              for<'a> &'a T: std::ops::Add<Output = T>
    {
        (T::zero()..len).map(|i| start + step * i).collect()
    }
    
    fn main() {
        println!("{:?}", positions(10, 2, 10));
    }
    

    You also need to require that T can be copied (or cloned, if you like) because the implementation of Add and Mul consumes the operands by value, which would mean that start + step * i could only be called once, except it needs to be called multiple times.

    0 讨论(0)
提交回复
热议问题