Как я могу связать переменную в функции карты с типом? - PullRequest
0 голосов
/ 18 октября 2018

Как я могу сказать компилятору, что это тип, который должен иметь функцию 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 голосов
/ 18 октября 2018

В настоящее время компилятор не догадывается, какой у вас тип целого числа.

Компилятору нужна подсказка:

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));
}
0 голосов
/ 18 октября 2018

Вы можете разыграть с as.

Изменить

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

на

.map(|(x, y)| (*x as u32).pow(y))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...