我有一个固定大小的数组切片 (&[[T; N]]
),我希望能够将其视为切片数组 ([&[T]; N]
)。输出数组的第 i
个元素将是原始切片中每个数组的所有第 i
个项目的切片:
fn magic_operation<T, const N: usize>(input: &[[T; N]]) -> [&[T]; N] {
todo!()
}
let original = &[
[10, 11, 12],
[20, 21, 22],
[30, 31, 32],
[40, 41, 42],
[50, 51, 52],
];
let new_view = magic_operation(original);
assert_eq!(new_view, [
&[10, 20, 30, 40, 50],
&[11, 21, 31, 41, 51],
&[12, 22, 32, 42, 52],
]);
我不知道这是否在任何 stdlib 方法中公开,而且我对不安全的 Rust 了解不够,无法自己尝试解决这个问题。这是否可能实现,也许是使用具有不同内存步幅的切片?
答案 0 :(得分:3)
这是不可能的。
切片中的锈元素是连续的;没有多余的空格。为了返回 &[10, 20, 30, 40, 50]
,该元素序列必须存在于其他地方以引用它们。原始输入中不存在该序列。
答案 1 :(得分:1)
如果我们谈论的是安全代码,那么这是不可能的。使用不安全的代码,您可以返回一个切片数组,但严格来说它不是数据的“视图”,我们必须通过复制值或引用来构造数据。这种不安全的编码不太可能是您需要或想要的。
Rust Playground 以下示例。
下面,该函数返回一个数组数组。 T
上的约束是使用 T::default()
作为初始值设定项所必需的。将 M x N 数组切片转换为 N x M 数组数组。
fn magic_operation<T, const N: usize,
const M: usize>(input: &[[T; N]; M]) -> [[T; M]; N]
where T: Default + Copy,
{
let mut v = [[T::default(); M]; N];
for i in 0..M {
for j in 0..N {
v[j][i] = input[i][j];
}
}
v
}
第二个示例显示了返回原始数据引用数组的函数。这不需要约束 T
,因为它使用 input
中第一个值的引用来初始化新数组 - 如果我们愿意,我们也可以在第一个示例中这样做,这将消除 { Default
上的 {1}} 约束。
T
还有一些 crate 可以灵活地创建新数组,array_init 就是其中之一。