Struct 访问D范围内的元素

Struct 访问D范围内的元素,struct,d,associative-array,Struct,D,Associative Array,我正在编写我的第一个D程序,并试图了解如何实现关联数组。不断出现的问题是,如果我创建如下数组: import std.stdio; import std.string; import std.array; void main(string[] args) { int[string] arr = ["first" : 1, "second" : 2]; } 一切都很好。但如果我尝试将arr移到main之外的结构中,我会得到一个错误:error:non-constant express

我正在编写我的第一个D程序,并试图了解如何实现关联数组。不断出现的问题是,如果我创建如下数组:

import std.stdio;
import std.string;
import std.array;

void main(string[] args) { 
   int[string] arr = ["first" : 1, "second" : 2]; 
}
一切都很好。但如果我尝试将arr移到main之外的结构中,我会得到一个错误:error:non-constant expression

这将抛出错误:

import std.stdio;
import std.string;
import std.array;

struct foo {
int[string] arr = ["first" : 1, "second" : 2]; 
}

void main(string[] args)
{ /* do stuff with foo */ }

我确信这是一个超级简单的修复,但这是我第一次尝试D。

类似的东西会奏效

struct Foo{
    int[string] arr;
}

void main(){
    Foo foo = Foo(["first" : 1, "second" : 2]);
}

这种限制来自于D模块中的符号不是有序的,而是“并行”存在的。这通常是件好事,因为:

  • 编译器可以并行地进行语义分析
  • 您不需要显式的前向声明(如在C中)来使用稍后在模块中声明的符号

考虑到这一点,请考虑此代码(全局范围):

如果允许初始值设定者使用运行时代码,
y1
y2
的值将取决于评估顺序,而评估顺序通常没有定义-所有全局值都是“相等”的

但对于局部函数变量,不存在这样的问题-它们被放置在堆栈上,因此计算顺序得到了完美定义(它是按词法顺序排列的):

因为编译器限制您在对全局或结构字段使用初始值设定项语法时只编译时间常量。构造函数(包括模块构造函数)仍然可以:

int[int] x;

static this()
{
    x = [ 1 : 1, 2 : 2 ];
}
AA literal看起来像一个合适的常量,但实际上它需要从运行时堆中分配内存。D足够聪明,可以接受一些这样的实体(甚至是一些类),并将它们放在固定的二进制内存段中,但AA可能会被扩展,所以需要适当的动态堆

另外请注意,D中的
struct
不能有默认构造函数:

struct foo
{
    int[string] arr;
    // this won't work:
    this() { this.arr = ["first" : 1, "second" : 2]; }
}

// need class instead

class boo
{
    int[string] arr;
    // fine:
    this() { this.arr = ["first" : 1, "second" : 2]; }
}

我认为问题在于结构大小是在编译时计算的,但是关联数组直到运行时才分配,编译器不知道它的大小等。将其声明为
enum
可能有效。我可能错了,但我想是这样的。你也可以尝试创建一个构造函数。我尝试创建了一个构造函数,但出现了一个错误,错误是:结构的默认构造函数只允许使用@disable和no body。因此,我只是将数组设置为enum,它似乎正在工作。如果您希望在运行时定义AA,则必须创建一个接受参数的构造函数。i、 e.struct foo{this(int[string]_a){this.arr=a;}}否则,正如L33Ts所说,在编译时使用枚举来定义它。编译时与运行时的对比是我学习D的最大的学习曲线,它来自Java背景,至少在你没有这样的背景的地方。这需要一点时间来适应:)!
int[int] x;

static this()
{
    x = [ 1 : 1, 2 : 2 ];
}
struct foo
{
    int[string] arr;
    // this won't work:
    this() { this.arr = ["first" : 1, "second" : 2]; }
}

// need class instead

class boo
{
    int[string] arr;
    // fine:
    this() { this.arr = ["first" : 1, "second" : 2]; }
}