如何将映射函数中的变量绑定到类型?

时间:2018-10-18 17:54:33

标签: rust

如何告诉编译器这是应该具有功能pow()的类型?

pub fn is_armstrong_number(num: u32) -> bool {

  [1, 2, 3, 4, 5, 6, 7, 8, 9].iter()
                             .zip( num.to_string().chars()
                             .map(|c| c.to_digit(10).unwrap()) )
                             .map(|(x, y)| *x.pow(y))
                             .fold(0, |acc, x| acc + x) == num

}

错误:

error[E0599]: no method named `pow` found for type `&{integer}` in the current scope
  --> src/lib.rs:10:47
   |
10 |                              .map(|(x, y)| *x.pow(y))
   |                                               ^^^

2 个答案:

答案 0 :(得分:3)

当前,编译器无法猜测整数的类型。

编译器需要提示:

pub fn is_armstrong_number(num: u32) -> bool {
    (1..10u32) // [1, 2, 3, 4, 5, 6, 7, 8, 9].iter()
        .zip(num.to_string().chars().map(|c| c.to_digit(10).unwrap()))
        .map(|(x, y)| x.pow(y))
        .sum::<u32>() // .fold(0, |acc, x| acc + x)
        == num
}

还要注意,您对armstrong_number的实现是错误的,正确的方法可能是:

fn is_armstrong_number(num: u32) -> bool {
    let buf = num.to_string();
    let y = buf.chars().count() as u32;
    buf.chars()
        .map(|c| c.to_digit(10).unwrap())
        .map(|x| x.pow(y))
        .sum::<u32>()
        == num
}

fn main() {
    assert!(is_armstrong_number(153));
    assert!(!is_armstrong_number(11));
}

我也尝试了这个有趣:

extern crate num; // 0.2.0

#[derive(Clone, Copy)]
struct DigitInteger<T> {
    num: T,
    radix: T,
}

impl<T> Iterator for DigitInteger<T>
where
    T: num::Unsigned + num::Zero + Copy,
{
    type Item = T;
    fn next(&mut self) -> Option<Self::Item> {
        if self.num != T::zero() {
            let ret = self.num % self.radix;
            self.num = self.num / self.radix;
            Some(ret)
        } else {
            None
        }
    }
}

fn is_armstrong_number<T>(num: T, radix: T) -> bool
where
    T: num::Unsigned,
    T: num::pow::Pow<T>,
    T: num::FromPrimitive,
    T: std::iter::Sum<<<DigitInteger<T> as std::iter::Iterator>::Item as num::traits::Pow<T>>::Output>,
    T: Copy,
{
    use num::pow::Pow;
    let d = DigitInteger { num, radix };
    let y = T::from_usize(d.count()).unwrap();
    d.map(|x| Pow::pow(x, y)).sum::<T>() == num
}

fn main() {
    assert!(is_armstrong_number(153u32, 10));
    assert!(!is_armstrong_number(11u32, 10));
    assert!(is_armstrong_number(1u32, 2));
    assert!(!is_armstrong_number(2u32, 2));
}

答案 1 :(得分:2)

您可以使用as进行投射。

更改

.map(|(x, y)| *x.pow(y))

.map(|(x, y)| (*x as u32).pow(y))