Другое решение заключается в прозрачной обработке Vec<T>
и [T]
с использованием AsRef
:
fn make_ship<T>(shape: &[T]) -> Vec<u32>
where
T: AsRef<[u32]>,
{
let mut ship: Vec<u32> = Vec::new();
for row_idx in 0..shape.len() {
let row = shape[row_idx].as_ref();
for col_idx in 0..row.len() {
let cell = row[col_idx];
if cell == 1 {
ship.push(col_idx as u32 + row_idx as u32 * WIDTH);
}
}
}
ship
}
Это обрабатывает следующее:
let glider = vec![vec![0, 1, 0], vec![0, 0, 1], vec![1, 1, 1]];
let glider = [[0, 1, 0], [0, 0, 1], [1, 1, 1]];
let glider = [vec![0, 1, 0], vec![0, 0, 1], vec![1, 1, 1]];
let glider = vec![[0, 1, 0], [0, 0, 1], [1, 1, 1]];
Еще лучшее решение - вообще не заботиться о срезах / векторах и использовать итераторы:
fn make_ship<'a, T, U>(shape: &'a T) -> Vec<u32>
where
&'a T: std::iter::IntoIterator<Item = U>,
U: std::iter::IntoIterator<Item = &'a u32>,
{
let mut ship: Vec<u32> = Vec::new();
for (row_idx, row) in shape.into_iter().enumerate() {
for (col_idx, &cell) in row.into_iter().enumerate() {
if cell == 1 {
ship.push(col_idx as u32 + row_idx as u32 * WIDTH);
}
}
}
ship
}
, который также обрабатывает описанные выше случаи, но может также обрабатывать тип, такой как @ 1013 * @ kazemakase, если он предоставляет такие итераторы.