我正在Rust中编写一些代码(主要是作为POC)。该代码采用2D数组,并将其传递给第二个函数以执行一些矩阵数学运算(我知道有一个标准库可以执行此操作,但我想习惯于工作原理)。
问题是分配给2D阵列会引起问题。
我的代码看起来像这样
fn main()
{
// first create a couple of arrays - these will be used
// for the vectors
let line1: [i32; 4] = [4, 2, 3, 3];
let line2: [i32; 4] = [3, 4, 5, 7];
let line3: [i32; 4] = [2, 9, 6, 2];
let line4: [i32; 4] = [5, 7, 2, 4];
// create two holding arrays and assign
let array_one = [line1, line3, line4, line2];
let array_two = [line2, line1, line3, line4];
// let's do the multiply
let result = matrix_multiply(&array_one, &array_two);
println!("{:?}", result);
}
fn matrix_multiply(vec1:&[&[i32;4];4], vec2:&[&[i32;4];4]) -> [[i32; 4];4]
{
// we need to deference the parameters passed in
let vec_one:[[i32;4];4] = vec1;
let vec_two:[[i32;4];4] = vec2;
// we need to store the sum
let mut sum = 0;
// we need to create the arrays to put the results into
let mut result = [[0i32; 4]; 4];
// loop through the two vectors
for vone in 0..4
{
for vtwo in 0..4
{
for k in 0..4
{
sum = sum + vec1[[vone].k] * vec2[[k].vtwo];
}
result[[vec_one].vec_two] = sum;
sum = 0;
}
}
return result;
}
Run Code Online (Sandbox Code Playgroud)
我也尝试过,result[vec_one][vec_two] = sum但是当我进行编译时,分配数组似乎有问题。
我在这里做错了什么?
我相信这是您的错误(至少其中之一):
<anon>:15:34: 15:44 error: mismatched types:
expected `&[&[i32; 4]; 4]`,
found `&[[i32; 4]; 4]`
(expected &-ptr,
found array of 4 elements) [E0308]
<anon>:15 let result = matrix_multiply(&array_one, &array_two);
^~~~~~~~~~
Run Code Online (Sandbox Code Playgroud)
问题是,数组的引用或取消引用不能在其嵌套的多个级别上进行。这是因为,例如,内容和大小在内存布局上[&[i32; 4]; 4]和[[i32; 4]; 4]根本上是不同的-前一个数组由指向其他数组的四个指针组成(总共4 * 4 = 16/8 * 4 = 32字节,具体取决于体系结构) ),而后者则由依次排列的四个数组组成(总共4 * 4 * 4 = 64字节)。我们根本没有办法从去[[i32; 4]; 4]到&[&[i32; 4]; 4]不重建外阵列,这锈永远不会为你做,因为实在是太多了魔力。
您实际上不需要使用内部引用;实际上,您甚至根本不需要通过引用传递这些数组:Copy类型数组Copy也是如此,因此您可以按值传递它们。它们足够小,不会对性能造成任何影响,并且编译器可能仍会自动对其进行优化:
fn main() {
// first create a couple of arrays - these will be used
// for the vectors
let line1: [i32; 4] = [4, 2, 3, 3];
let line2: [i32; 4] = [3, 4, 5, 7];
let line3: [i32; 4] = [2, 9, 6, 2];
let line4: [i32; 4] = [5, 7, 2, 4];
// create two holding arrays and assign
let array_one = [line1, line3, line4, line2];
let array_two = [line2, line1, line3, line4];
// let's do the multiply
let result = matrix_multiply(array_one, array_two);
println!("{:?}", result);
}
fn matrix_multiply(vec1: [[i32; 4]; 4], vec2: [[i32; 4]; 4]) -> [[i32; 4]; 4] {
// we need to create the arrays to put the results into
let mut result = [[0i32; 4]; 4];
// loop through the two vectors
for vone in 0..4 {
for vtwo in 0..4 {
let mut sum = 0;
for k in 0..4 {
sum += vec1[vone][k] * vec2[k][vtwo];
}
result[vone][vtwo] = sum;
}
}
result
}
Run Code Online (Sandbox Code Playgroud)
(在这里尝试)
根据当前的社区实践(花括号位置,间距等),我还使您的代码更加惯用,并且修复了访问数组的怪异语法。