我对锈病很陌生,而且还习惯了所有权模式。我已经写完了这本书的第8章,并试图解决这个问题:
给定一个整数列表,使用一个向量并返回列表的...模式(最常见的值;哈希映射将在这里有所帮助)。
这是我的解决方案:
use std::collections::HashMap;
pub fn vectors() {
let mut numbers: Vec<i32> = vec![
12, 15, 6, 44, 6, 32, 77, 77, 77, 77, 77, 94, 6, 2, 67, 0, 25, 14, 84, 81, 59, 31, 7, 9,
];
println!("{:?}", numbers);
// calculating and displaying the mode
let mut numbers_count = HashMap::new();
for num in &numbers {
let count = numbers_count.entry(num).or_insert(0);
*count += 1;
}
let mut mode = 0;
let mut prev_value = 0;
for (key, value) in &numbers_count {
if *value > prev_value {
prev_value = *value;
mode = **key;
}
}
println!("Mode: {}", mode);
}密码有效但是..。这被认为是个好办法吗?在我完成之后,我在网上搜索了一下,发现这一种选择似乎更被接受了。而且,在第21行中,我不得不两次使用取消引用操作符;这可以吗,还是被认为是错误的做法?
发布于 2022-08-18 17:11:43
这看起来像一些非常好的代码,但是有一些事情我想要强调,尽管:
numbers不需要声明为可变的(因此也不应该是可变的)。总是声明与最不强大的借款规格可能。这简化了编译器的工作,并通过公开意外的可更改性使检查器更有价值。numbers和numbers_count并不是名副其实的名字,但是代码很小,而且非常清晰,所以应该没问题。Iterator::max_by将整个映射迭代和两个变量浓缩为: let (mode,_) = numbers_count.iter() .max_by (_,lv),(_,rv).expect(“我们至少需要一个值来计算模式”);返回**模式;请注意,此更新引入了一个微妙的语义差异,因为iter()中的最后一个元素在列表中的项最多,而不是第一个。但是,由于从一开始就没有排序由一个iter()返回的HashMap,所以这不应该有任何区别:)vectors pub fn mode_v1( numbers:&Vec) -> i32 { let mut numbers_count = HashMap::new();对于数字中的num { let count = numbers_count.entry(num).or_insert(0);*count += 1;}.请注意,这是如何将借款行为强制执行转移到方法的调用方的。当然,这可以进一步扩展到诸如向量中没有元素,但在确定模式时不想恐慌的情况。另一个有趣的步骤是通过接受更多的集合-y,从Vec<i32>的类型范围移到更通用的东西上。对于锈病,有Slice,可以很容易地引入如下方式: pub fn模式(数字:&i32) -> Option {/或i32,这取决于错误行为,然后可以扩展到包含泛型,以允许更多的输入。也许你想要一个i64,S,i8或者其他什么东西的列表模式?:pub fn,mode(元素:&T) -> Option,其中T: Ord + Hash + Copy {https://codereview.stackexchange.com/questions/278947
复制相似问题