我花了几个小时试图理解为什么String::from_utf8在从字节数组转换时包含转义符,例如"u/{x}"
。这是来自扫雷演习的练习,该练习鼓励使用字节而不是字符来提高效率https://exercism.org/tracks/rust/exercises/minesweeper
如果我使用了任何不良做法,我深表歉意,我是Rust 的新手
pub fn annotate(minefield: &[&str]) -> Vec<String> {
const BOMB_COUNT_INDEXES: [(isize, isize); 8] = [
(-1, -1), (-1, 0), (-1, 1),
(0, -1), /* · */ (0, 1),
(1, -1), (1, 0), (1, 1)
];
minefield.iter()
.enumerate()
.map(|(row_n, row_str)| {
String::from_utf8(
row_str.as_bytes()
.iter()
.enumerate()
.map(|(column_n, column_byte)| {
if *column_byte != b'*' {
let mut bombs_n: u8 = 0;
for (x, y) in BOMB_COUNT_INDEXES {
if let Some(&row) = minefield.get((row_n as isize + x) as usize) {
if let Some(&c) = row.as_bytes().get((column_n as isize + y) as usize) {
if c == b'*' { bombs_n += 1; }
}
}
}
if bombs_n > 0 { return bombs_n }
}
return *column_byte
}).collect::<Vec<u8>>()
).unwrap()
}).collect()
}
您正在将周围的炸弹汇总为bombs_n
。但是,如果您有3
炸弹,这与显示字符'3'
不同;CCD_ 5在ASCII中表示为CCD_。
你需要做一些类似的事情:
if bombs_n > 0 { return bombs_n + b'0' }
如果你觉得新奇,也可以使用char::from_digit
。