我正在学习D,并使用run.dlang.io进行调试。下面的代码在run.dlang.io上运行没有问题:
import std.stdio;
import std.algorithm;
import std.range;
import std.typecons;
static bool even(Tuple!(ulong, double) a) {
return (a[0] & 1) == 0;
}
void main() {
double[] arr = [31, 22, -3, 44, 51, 26, 47, 58, 19, 10];
auto res1 = arr.enumerate.filter!(even).map!(a => a[1]);
writeln(res1);
}
但是,DMD32 v2.088在Windows 10上编译完全相同的代码dmd temp.d
时会引发异常。
Error: function temp.even(Tuple!(ulong, double) a) is not callable using argument types (Tuple!(uint, "index", double, "value"))
虽然LDC编译器(1.18.0-beta1):(基于DMD v2.088.0和LLVM 8.0.1)可以编译相同的文件而没有问题。
run.dlang.io使用2.087 dmd编译器,并且以某种方式神奇地起作用,为什么在Windows上不起作用?
在Windows上,您的应用程序默认情况下是为32位构建的。在OSX和Linux(run.dlang.io正在运行)上,默认情况下会以64位进行构建。
因此,数组索引分别为uint和ulong。在您的代码中,您使用了Tuple!(ulong, double)
,但在32位上使用uint索引进行了调用。
而不是使用ulong / uint,您应该使用size_t
作为索引,它映射到uint / ulong。这在object.d中定义,默认情况下已包含。
因此,如果您将功能更改为
static bool even(Tuple!(size_t, double) a) {
return (a[0] & 1) == 0;
}
它将同时在32位和64位上运行。
在Windows上,您还可以通过使用--arch=x86_64
或dmd标志-m64
运行它来使用dub测试您的代码,该代码应该已经可以正常工作而无需更改。我建议始终在32位和64位上同时测试您的应用程序,以确保在需要的地方使用size_t
。