如何告诉编译器这是应该具有功能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))
| ^^^
答案 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))