2015-03-31 101 views
0

我正在編寫我的第一個D程序,並試圖瞭解如何實現關聯數組。不斷出現的問題是,如果我創建一個像這樣的數組:訪問D中範圍內的元素

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

void main(string[] args) { 
    int[string] arr = ["first" : 1, "second" : 2]; 
} 

一切都編譯好。但如果我嘗試並將arr移動到main之外 - 進入一個結構體,我得到一個錯誤:Error:非常量表達式。

,這將引發錯誤:

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.

第一次嘗試
+1

我認爲這個問題是結構尺寸在編譯時進行計算,但關聯數組沒有分配,直到運行時和編譯器不知道它的大小等。聲明它爲'enum'可能工作。我可能是錯的,但我認爲是這樣。你也可以嘗試製作一個構造函數。 – Bauss 2015-03-31 05:11:20

+0

我試着創建一個構造函數,並得到一個錯誤,說:結構的默認構造函數只允許與@disable和沒有正文。所以我只是將數組設置爲枚舉,它似乎工作。 – StillLearningToCode 2015-03-31 05:20:44

+0

如果您希望在運行時定義AA,則必須創建一個接受參數的構造函數。即struct foo {this(int [string] _a){this。arr = a;否則,正如L33T所說的那樣,在編譯時使用enum來定義它。 Compile-Time vs Runtime是我學習D的最大的學習曲線,來自Java背景,至少在你沒有的地方。這將需要一點習慣:)! – 2015-03-31 08:24:20

回答

5

此限制來自於這樣一個事實,即D模塊中的符號不​​是有序的,而是「並行」存在的。這通常是一件好事,因爲:

  • 編譯器能做語義分析並行
  • 你不(在C等)需要明確的向前聲明使用後的模塊中聲明符號

考慮到這一點,考慮下面的代碼(全球範圍):使用運行時代碼

int x; 
int foo() { return ++x; } 
int y1 = foo(); 
int y2 = foo(); 

如果被允許用於初始化的y1一個值nd y2將取決於通常未定義的評估順序 - 所有全局變量都是「相等的」。

但對於本地函數變量不存在這樣的問題 - 它們被放置在棧,從而評價順序完全被定義(這是詞彙順序):

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文字可能看起來像一個適當的恆定的,但它實際需要分配的運行時堆內存。 D足夠聰明,可以接受一些這樣的實體(甚至是某些類)並將它們放入固定的二進制存儲器部分,但AA可以擴展,因此需要適當的動態堆。

同時請注意,在struct可以d沒有默認的構造函數:

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]; } 
} 
2

像這樣的事情會工作。

struct Foo{ 
    int[string] arr; 
} 

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