'&[T] changed to Vec<&T>

I wrote a function that accepts a slice of single digit numbers and returns a number.

pub fn from_digits<T>(digits: &[T]) -> T
where
    T: Num + FromPrimitive + Add + Mul + Copy,
{
    let mut ret: T = T::zero();
    let ten: T = T::from_i8(10).unwrap();
    for d in digits {
        ret = ret * ten + **d;
    }
    ret
}

For example, from_digits(&vec![1,2,3,4,5]) returns 12345. This seems to work fine.

Now, I want to use this function in another code:

let ret: Vec<Vec<i64>> = digits // &[i64]
  .iter()                      // Iter<i64>
  .rev()                       // impl Iterator<Item = i64>
  .permutations(len)           // Permutations<Rev<Iter<i64>>>
  .map(|ds| from_digits(&ds))  // <-- ds: Vec<&i64>
  .collect();

The problem is that after permutations(), the type in the lambda in map is Vec<&i64>, not Vec<i64>. This caused the compile error, as the expected parameter type is &[T], not &[&T].

I don't understand why the type of ds became Vec<&i64>. I tried to change the from_digits like this:

pub fn from_digits<T>(digits: &[&T]) -> T
...

But I am not sure if this is the correct way to fix the issue. Also, this caused another problem that I cannot pass simple data like vec![1,2,3] to the function.

Can you let me know the correct way to fix this?



Solution 1:[1]

The problem is that slice's iter() function returns an iterator over &T, so &i64.

The fix is to use the Iterator::copied() or Iterator::cloned() adapters that converts and iterator over &T to an iterator over T when T: Copy or T: Clone, respectively:

digits.iter().copied().rev() // ...

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Chayim Friedman