我正在尝试将数据从matrixA
复制到matrixB
M
,但我收到错误:
app.d(20): Error: function app.M (double[][] s, ref double[][] d, int row, int col) is not callable using argument types (double[5][5], double[][], int, int)
代码:
double matrixA[5][5] = [ [ 1.0, 2.0, 3.0, 4.0, 5.0 ],
[ 1.0, 2.0, 3.0, 4.0, 5.0 ],
[ 1.0, 2.0, 3.0, 4.0, 5.0 ],
[ 1.0, 2.0, 3.0, 4.0, 5.0 ],
[ 1.0, 2.0, 3.0, 4.0, 5.0 ] ];
double matrixB[][];
void M(double[][] s, ref double[][] d, int row, int col)
{
d.length = row;
foreach (i; 0 .. d.length)
d[i].length = col;
d = s;
}
void main()
{
M(matrixA, matrixB, 5, 5);
}
答案 0 :(得分:1)
你似乎有两个问题。一个ref
,一个尝试隐式转换无效。
在D中使用ref
时,类型必须完全匹配。隐式转换不会削减它。所以,例如,如果你有
int[5] a = [1, 2, 3, 4, 5];
int[] b = a;
你有
void foo(int[] bar) {}
然后这两行都会编译
foo(a);
foo(b);
因为静态数组会隐式转换为动态数组,但是如果你更改它以便foo
通过ref获取其参数
void foo(ref int[] a) {...}
然后
foo(a); // won't compile, because a is int[5], not int[]
foo(b); // compiles, because b is int[]
因此,如果您有一个需要ref double[][]
的函数,则必须将double[][]
传递给它。隐式转换为double[][]
的任何内容都无效。
现在,情况比这更糟糕,因为你传递的是double[5][5]
,它不会隐式转换为double[][]
。因此,即使ref
接受了隐式转换,您的代码也无效,即使您删除了ref
,您的代码也无效。可以对单维静态数组进行切片(隐式或显式)以获得动态数组,但是您无法对多维静态数组进行切片以获得动态数组。
double[5] a;
double[] b = b; // compiles
double[] c = a[]; // compiles
double[5][5] d;
double[][] e = d; // does not compile
double[][] f = d[]; // does not compile
AFAIK,如果您要将double[5][5]
分配给double[][]
,则必须执行类似
double[5][5] a;
double[][] b;
foreach(i; row; a)
b[i] = row[];
最近在支持使用多维切片的用户定义类型方面做了一些工作,因此可以使用我不知道的语法将double[5][5]
切换为double[][]
,但它可能只适用于用户定义的类型。无论如何,没有从double[5][5]
到double[][]
的隐式转换,隐式转换不适用于ref
。
答案 1 :(得分:0)
目前使多维动态数组在静态数组中运行起来有点困难。
要回答您的问题,您可以使用模板定义一个功能:
void M(T)(T s, ref double[][] d, int row, int col)
if (is(typeof(s[0][0]) : double))
{ }
此声明表明源s
可以是任何类型T
,这样在0,0处索引T会返回一个double(或者可以隐式转换为double的内容。
但是,您的功能体将无法正常显示。当它们的大小不同时,你不能只将s分配给d。这可能更接近您的期望:
{
d.length = row;
foreach(i ; 0 .. d.length)
d[i] = s[i][0..col].dup;
}