Robot Name
1. Readme
机器人名称
管理机器人工厂设置.
当机器人从工厂车间出来时,他们没有名字。
第一次启动时,会生成一个随机名称,格式为两个大写字母后跟三个数字,如 RX837 或 BC811。
每隔一段时间我们就需要将机器人重置为出厂设置,这意味着他们的名字会被擦除。下次你问,它会以一个新的随机名称回复。
名称必须是随机的:它们不应遵循可预测的顺序。随机名称表示发生碰撞的风险。您的解决方案必须确保每个现有机器人都具有唯一名称。
资源
与 Paul Blackwell 在 gSchool 的调试会议.http://gschool.it
2. 开始你的表演
pub struct Robot; impl Robot { pub fn new() -> Self { unimplemented!("Construct a new Robot struct."); } pub fn name(&self) -> &str { unimplemented!("Return the reference to the robot's name."); } pub fn reset_name(&mut self) { unimplemented!("Assign a new unique name to the robot."); } }
3. 测试代码查看
# #![allow(unused_variables)] #fn main() { fn assert_name_matches_pattern(n: &str) { assert!(n.len() == 5, "name is exactly 5 characters long"); assert!( n[0..2].chars().all(|c| c >= 'A' && c <= 'Z'), "name starts with 2 uppercase letters" ); assert!( n[2..].chars().all(|c| c >= '0' && c <= '9'), "name ends with 3 numbers" ); } fn assert_name_is_persistent(r: &Robot) { // The type system already proves this, but why not. let n1 = r.name(); let n2 = r.name(); let n3 = r.name(); assert_eq!(n1, n2); assert_eq!(n2, n3); } #[test] fn test_name_should_match_expected_pattern() { let r = Robot::new(); assert_name_matches_pattern(r.name()); } #[test] //#[ignore] fn test_name_is_persistent() { assert_name_is_persistent(&Robot::new()); } #[test] //#[ignore] fn test_different_robots_have_different_names() { let r1 = Robot::new(); let r2 = Robot::new(); assert_ne!(r1.name(), r2.name(), "Robot names should be different"); } #[test] //#[ignore] fn test_new_name_should_match_expected_pattern() { let mut r = Robot::new(); assert_name_matches_pattern(r.name()); r.reset_name(); assert_name_matches_pattern(r.name()); } #[test] //#[ignore] fn test_new_name_is_persistent() { let mut r = Robot::new(); r.reset_name(); assert_name_is_persistent(&r); } #[test] //#[ignore] fn test_new_name_is_different_from_old_name() { let mut r = Robot::new(); let n1 = r.name().to_string(); r.reset_name(); let n2 = r.name().to_string(); assert_ne!(n1, n2, "Robot name should change when reset"); } #}
4. 答案
# #![allow(unused_variables)] #fn main() { extern crate rand; use rand::{thread_rng, Rng}; pub struct Robot { name: String, } fn generate_name() -> String { let mut s = String::with_capacity(5); static LETTERS: &'static [u8] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZ"; static NUMBERS: &'static [u8] = b"0123456789"; for _ in 0..2 { s.push(thread_rng().choose(LETTERS).unwrap().clone() as char); } for _ in 0..3 { s.push(thread_rng().choose(NUMBERS).unwrap().clone() as char); } s } impl Robot { pub fn new() -> Robot { Robot { name: generate_name(), } } pub fn name<'a>(&'a self) -> &'a str { &self.name[..] } pub fn reset_name(&mut self) { self.name = generate_name(); } } #}