-
Notifications
You must be signed in to change notification settings - Fork 1.1k
collections/hashmap #172
-
collections/hashmap
Learning Rust By Practice, narrowing the gap between beginner and skilled-dev with challenging examples, exercises and projects.
Beta Was this translation helpful? Give feedback.
All reactions
-
👍 13 -
😄 4 -
🎉 1 -
❤️ 2
Replies: 15 comments 9 replies
-
题目2 的答案有误
let teams_map2: HashMap<,> = teams.into_iter().collect();
collect 会报错, value of type HashMap<&str, i32>
cannot be built from std::iter::Iterator<Item=&(&str, i32)>
需改成 let teams_map2: HashMap<,> = teams.iter().cloned().collect();
原理我还在研究
Beta Was this translation helpful? Give feedback.
All reactions
-
个人猜测:
collect 会涉及到所有权的转换问题,需要先 cloned()/copid(),加完 clone(),会有个 warning
warning: this method call resolves to <&[T; N] as IntoIterator>::into_iter
(due to backwards compatibility), but will resolve to <[T; N] as IntoIterator>::into_iter in Rust 2021
into_iter -> iter 这 warning 没看懂
Beta Was this translation helpful? Give feedback.
All reactions
-
...... 这是edition = "2018" 才有的问题,edition = "2021" 就没这问题了
Beta Was this translation helpful? Give feedback.
All reactions
-
👍 4
-
第五题从哪里可以体现出需要自反性呢?
Beta Was this translation helpful? Give feedback.
All reactions
-
第五题不是所有权的问题吗?自反性是啥
Beta Was this translation helpful? Give feedback.
All reactions
-
自反性:自己 == 自己,如果是浮点数的话就不满足自反性
Beta Was this translation helpful? Give feedback.
All reactions
-
👍 2
-
有点奇怪,
vec使用into_iter()时候是会消耗vec的,为什么下面这句话没有把teams所有权给消耗掉?
let teams_map2 = teams.into_iter().collect(); //
而使用下面iter()代替into_iter()时候反而出现了,上面@quarksb
说的edition = "2018" 才有的问题
let teams_map2 = teams.iter().collect(); //
Beta Was this translation helpful? Give feedback.
All reactions
-
Here are the reasons:
- teams is a
array
, not a vector. array
is primitive type, and it implementsCopy
andClone
traits in default.
Thus, teams.into_iter()
would not consume the ownership. In fact, it copy
the array and convert the copied array into a new iterator.
If I missed anything, please let me know. THX!
References:
Beta Was this translation helpful? Give feedback.
All reactions
-
🚀 5
-
@twandylue Thanks your answer!
Beta Was this translation helpful? Give feedback.
All reactions
-
楼上是对的,into_iter()确实会取得所有权,但如果每个元素都实现了copy,那它会直接复制,而不会移动。
Beta Was this translation helpful? Give feedback.
All reactions
-
mark
Beta Was this translation helpful? Give feedback.
All reactions
-
lala
Beta Was this translation helpful? Give feedback.
All reactions
-
1、HashMap
的基本操作
use std::collections::HashMap; fn main() { let mut scores = HashMap::new(); //需要保持<key,value>类型一致 scores.insert("Sunface", 98); scores.insert("Daniel", 95); scores.insert("Ashley", 69); scores.insert("Katie", 58); // get 返回一个 Option<&V> 枚举值 let score = scores.get("Sunface"); assert_eq!(score, Some(&98)); if scores.contains_key("Daniel") { // 索引返回一个值 V let score = scores["Daniel"]; assert_eq!(score, 95); scores.remove("Daniel"); } assert_eq!(scores.len(), 3); for (name, score) in scores { println!("The score of {} is {}", name, score) } }
2、
(1)collect
的用法
use std::collections::HashMap; fn main() { let teams = [ ("Chinese Team", 100), ("American Team", 10), ("France Team", 50), ]; let mut teams_map1 = HashMap::new(); for team in &teams { teams_map1.insert(team.0, team.1); } // 使用两种方法实现 team_map2 // 提示:其中一种方法是使用 `collect` 方法 let teams_map2:HashMap<_,_>=teams.into_iter().collect(); assert_eq!(teams_map1, teams_map2); println!("Success!") }
(2)暴力复制
use std::collections::HashMap; fn main() { let teams = [ ("Chinese Team", 100), ("American Team", 10), ("France Team", 50), ]; let mut teams_map1 = HashMap::new(); for team in &teams { teams_map1.insert(team.0, team.1); } // 使用两种方法实现 team_map2 // 提示:其中一种方法是使用 `collect` 方法 let teams_map2=teams_map1.clone(); assert_eq!(teams_map1, teams_map2); println!("Success!") }
3、理解
// 填空 use std::collections::HashMap; fn main() { // 编译器可以根据后续的使用情况帮我自动推断出 HashMap 的类型,当然你也可以显式地标注类型:HashMap<&str, u8> let mut player_stats = HashMap::new(); // 查询指定的 key, 若不存在时,则插入新的 kv 值 player_stats.entry("health").or_insert(100); assert_eq!(player_stats["health"], 100); // 通过函数来返回新的值 player_stats.entry("health").or_insert_with(random_stat_buff); assert_eq!(player_stats["health"], 100); let health = player_stats.entry("health").or_insert(50); assert_eq!(*health, 100); *health -= 50; assert_eq!(*health, 50); println!("Success!") } fn random_stat_buff() -> u8 { // 为了简单,我们没有使用随机,而是返回一个固定的值 42 }
4、
// 修复错误 // 提示: `derive` 是实现一些常用特征的好办法 use std::collections::HashMap; #[derive(Eq,Hash,PartialEq,Debug)] struct Viking { name: String, country: String, } impl Viking { fn new(name: &str, country: &str) -> Viking { Viking { name: name.to_string(), country: country.to_string(), } } } fn main() { // 使用 HashMap 来存储 viking 的生命值 let vikings = HashMap::from([ (Viking::new("Einar", "Norway"), 25), (Viking::new("Olaf", "Denmark"), 24), (Viking::new("Harald", "Iceland"), 12), ]); // 使用 derive 的方式来打印 viking 的当前状态 for (viking, health) in &vikings { println!("{:?} has {} hp", viking, health); } }
5、所有权会被 HashMap
调用
// 修复错误,尽可能少的去修改代码 // 不要移除任何代码行! use std::collections::HashMap; fn main() { let v1 = 10; let mut m1 = HashMap::new(); m1.insert(v1, v1); println!("v1 is still usable after inserting to hashmap : {}", v1); let v2 = "hello".to_string(); let mut m2 = HashMap::new(); // 所有权在这里发生了转移 m2.insert(v2.clone(), v1); assert_eq!(v2, "hello"); println!("Success!") }
Beta Was this translation helpful? Give feedback.
All reactions
-
第四题不明白,struct Viking {
name: String,
country: String,
}内都是String,String原来就有实现Hash和Eq,那这个结构体应该也是自动实现了Viking才对。为什么仍然要加#[derive(Hash, Eq, PartialEq, Debug)]才不报错呢?
Beta Was this translation helpful? Give feedback.
All reactions
-
应该是结构体不会自动实现,而集合会
Beta Was this translation helpful? Give feedback.
All reactions
-
done
Beta Was this translation helpful? Give feedback.
All reactions
-
- done
Beta Was this translation helpful? Give feedback.
All reactions
-
three way to solve question number 2:
use std::collections::HashMap;
fn main() {
let teams : [(&str, i32); 3] = [
("Chinese Team", 100),
("American Team", 10),
("France Team", 50),
];
let mut teams_map1 = HashMap::new();
for team in &teams {
teams_map1.insert(team.0, team.1);
}
// IMPLEMENT team_map2 in two ways
// Tips: one of the approaches is to use `collect` method
// let teams_map2 : HashMap<&str, i32> = teams.into();
// let teams_map2 : HashMap<&str, i32> = teams.into_iter().collect();
let teams_map2 : HashMap<&str, i32> = HashMap::from(teams);
assert_eq!(teams_map1, teams_map2);
println!("Success!");
}
Beta Was this translation helpful? Give feedback.
All reactions
-
done~~~
Beta Was this translation helpful? Give feedback.
All reactions
-
fn random_stat_buff() -> u8 { // 为了简单,我们没有使用随机,而是返回一个固定的值 42 }
宇宙的终极答案(
Beta Was this translation helpful? Give feedback.
All reactions
-
mark finished
Beta Was this translation helpful? Give feedback.
All reactions
-
Day 10
Done✅
Beta Was this translation helpful? Give feedback.
All reactions
-
Success(5/5)
Beta Was this translation helpful? Give feedback.
All reactions
-
done
Beta Was this translation helpful? Give feedback.