原文
struct A
{
int[] i;
}
struct B
{
A[] a = [A.init];
}
A和B
如上,代碼:
auto b1 = B.init;
b1.a[0].i ~= 1;
b1.a ~= A.init;
b1.a[0].i ~= 11;
b1.a[1].i ~= 12;
b1.writeln;
auto b2 = B();
b2.writeln;
//期望相同
B([A([1, 11]), A([12])])
B([A([])])
期望編譯.但代碼:
B b1; // auto b1 = B.init;
b1.a[0].i ~= 1;
b1.a ~= A.init;
b1.a[0].i ~= 11;
b1.a[1].i ~= 12;
b1.writeln;
B b2; // auto b2 = B();
b2.writeln;
//沒有列印期望的
B([A([1, 11]), A([12])])
B([A([1])])
為什麼?
A[] a = [A.init];
問題
在此,它是引用在B的
所有副本
中共享的
靜态數組執行個體
.幾乎肯定你不想要它.
B.a[0]
是跨不同預設構造的所有
B
的
*相同對象*
.
不要
這樣.隻有
基本值
和
不變串
才這樣初化.用
數組或類對象
,可能得到共享.
如果在
構造器
(需要個
參數
)或
工廠
函數中初化,會獲得
更加一緻
行為,因為
每個執行個體
都有
自己
的數組.
至于為什麼
B()
和
B.init
在此不同,我不知道,可能是
編譯器
的
一些微妙
實作.
我最近實驗:
struct Xml {
string beg;
string end = "/>"; // 所有執行個體共享
// 無配置設定.
// ...
}
這不是錯誤:
void main()
{
struct B
{
struct A
{
int i = 10;
}
A[] a = [A.init];
}
B[2] b;
assert(b[0].a.ptr is b[1].a.ptr);
}
這不是錯誤.他們指向記憶體中
A的
完全相同
執行個體
:
這裡是:編譯時配置設定了
單個全局
的在所有
B.init
執行個體之間共享的
A[]
.就像如下:
struct B
{
struct A
{
int i = 10;
}
static A[] globalArray = [A.init];
A[] a = globalArray;
}
我想調整
預設構造器
,但
構
不能有
自定義
版.
添加
帶參構造器
,似乎是個
侵改
.
有靜态
opCall
,也像
侵改
.
import std.stdio;
struct A
{
int[] i;
}
struct B
{
A[] a = [A.init];
static B opCall()
{//
return B.init;
}
}
void main()
{
auto b1 = B.init;
b1.writeln;
B b2 = B();
b2.writeln;
B b3;
b3.writeln;
}
靜态數組
是值類型.
複制
靜态數組時,
副本
資料
存儲
在與
原始
數組不同的
記憶體塊
中:
int[1] a = [1];
int[1] b = a;
assert(&a[0] !is &b[0]);
//記憶體不同
int[] a = [1];
int[] b = a;
assert(&a[0] is &b[0]);
int[] a = [1];
int[] b = a.dup;
assert(&a[0] !is &b[0]);
//不同記憶體