Implementing generic digits function

Viewed 76

I wanted to implement digits function which returns a vector of individual digits for a given number. For example, digits(12345) should return Vec[1, 2, 3, 4, 5].

After struggling with some small issues, I ended up with the following code:

fn digits<T, R>(mut n: T) -> Vec<R> where 
    T: Num + Rem + DivAssign + FromPrimitive + Copy,
    R: Num + TryFrom<T>
{
    let zero = T::zero();
    let ten: T = T::from_i8(10).unwrap();
    let mut acc: Vec<R> = Vec::new();

    while n != zero {
        let d: R = R::try_from(n % ten).ok().unwrap();
        acc.push(d);
        n /= ten;
    }
    acc.reverse();
    acc
}

And this seems to working fine with most primitive integer types. The problem is that the input type T should implement Copy, I can't use this function for BigInt or BigUint as Copy is not implemented for them.

If I remove Copy trait from T, the compilation fails due to various errors with such messages as bowwor of moved value: n or use of moved value: ten.

How can fix this so it can work with primitive integers as well as BigInt and BigUint?

1 Answers

Anything that implements Copy does Clone too, also BigInt and BigUint implements Clone. So you could change the constraint to Clone instead and explicitly add any clone that you may need.

fn digits<T, R>(mut n: T) -> Vec<R> where 
    T: Num + Rem + DivAssign + FromPrimitive + Clone,
    R: Num + TryFrom<T>
{
...
}

Playground

Related