访问 D 中范围内的元素
accessing an element in a range in D
我正在编写我的第一个 D 程序,并试图了解如何实现关联数组。不断出现的问题是,如果我创建一个数组,如:
import std.stdio;
import std.string;
import std.array;
void main(string[] args) {
int[string] arr = ["first" : 1, "second" : 2];
}
编译一切正常。但是如果我尝试将 arr 移出 main-- 到一个结构中,我会收到一条错误消息:错误:非常量表达式。
这会引发错误:
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 模块中的符号没有顺序但存在的事实 "in parallel"。这通常是一件好事,因为:
- 编译器可以并行进行语义分析
- 您不需要显式前向声明(如在 C 中)即可使用稍后在模块中声明的符号
考虑到这一点,请考虑以下代码(全局范围):
int x;
int foo() { return ++x; }
int y1 = foo();
int y2 = foo();
如果初始化器允许使用 运行-时间代码,y1
和 y2
的值将取决于通常未定义的评估顺序 - 所有全局变量都是 "equal".
但对于局部函数变量没有这样的问题 - 它们被放置在堆栈中,因此计算顺序是完美定义的(它是按词法顺序):
void foo()
{
int x;
int foo() { return ++x; }
int y1 = foo(); // will always be 1
int y2 = foo(); // will always be 2
}
因为在对全局变量或结构字段使用初始化语法时,编译器限制您只能使用编译时常量。构造函数(包括模块构造函数)仍然可以:
int[int] x;
static this()
{
x = [ 1 : 1, 2 : 2 ];
}
AA 文字可能看起来像一个适当的常量,但它实际上需要从 运行-time 堆中分配内存。 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]; }
}
我正在编写我的第一个 D 程序,并试图了解如何实现关联数组。不断出现的问题是,如果我创建一个数组,如:
import std.stdio;
import std.string;
import std.array;
void main(string[] args) {
int[string] arr = ["first" : 1, "second" : 2];
}
编译一切正常。但是如果我尝试将 arr 移出 main-- 到一个结构中,我会收到一条错误消息:错误:非常量表达式。
这会引发错误:
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 模块中的符号没有顺序但存在的事实 "in parallel"。这通常是一件好事,因为:
- 编译器可以并行进行语义分析
- 您不需要显式前向声明(如在 C 中)即可使用稍后在模块中声明的符号
考虑到这一点,请考虑以下代码(全局范围):
int x;
int foo() { return ++x; }
int y1 = foo();
int y2 = foo();
如果初始化器允许使用 运行-时间代码,y1
和 y2
的值将取决于通常未定义的评估顺序 - 所有全局变量都是 "equal".
但对于局部函数变量没有这样的问题 - 它们被放置在堆栈中,因此计算顺序是完美定义的(它是按词法顺序):
void foo()
{
int x;
int foo() { return ++x; }
int y1 = foo(); // will always be 1
int y2 = foo(); // will always be 2
}
因为在对全局变量或结构字段使用初始化语法时,编译器限制您只能使用编译时常量。构造函数(包括模块构造函数)仍然可以:
int[int] x;
static this()
{
x = [ 1 : 1, 2 : 2 ];
}
AA 文字可能看起来像一个适当的常量,但它实际上需要从 运行-time 堆中分配内存。 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]; }
}