先看一段代碼:
void?main(){
????int[]?c?=?[1,2,3];
????foreach(inout?int?i;?c){
????????writef(&i);
????????writef(",?");
????}
????writefln("");
????c.length?=?2;
????foreach(inout?int?i;?c){
????????writef(&i);
????????writef(",?");
????}
????writefln("");
????c.length?=?3;
????foreach(inout?int?i;?c){
????????writef(&i);
????????writef(",?");
????}
????writefln("");
????c.length?=?4;
????foreach(inout?int?i;?c){
????????writef(&i);
????????writef(",?");
????}
????writefln("");
}
它輸出結果如下:
B7D19FB0, B7D19FB4, B7D19FB8,
B7D19FB0, B7D19FB4,
B7D19FB0, B7D19FB4, B7D19FB8,
B7D1CFA0, B7D1CFA4, B7D1CFA8, B7D1CFAC,
可以看到前3行地址相同,后面一行地址不同。為什么?
D語言的數組分配是內存緊湊的,當減小數組長度減小時,只需要修改切片大小而不需要重新分配。當長度變大時,也會檢查原來的緩沖區是否夠大,以確定是否需要重新分配空間。注意第2次操作時把長度恢復為原來大小時,并非真的恢復了原來的狀態,后面長出來的元素會被初始化為默認值。
再來看一個:
void?main(){
????int[]?c?=?[1,2,3];
????int[]?d?=?c;
????foreach(inout?int?i;?c){
????????writef(&i);
????????writef(",?");
????}
????writefln("");
????foreach(inout?int?i;?d){
????????writef(&i);
????????writef(",?");
????}
????writefln("");
????d.length?=?2;
????foreach(inout?int?i;?c){
????????writef(&i);
????????writef(",?");
????}
????writefln("");
????foreach(inout?int?i;?d){
????????writef(&i);
????????writef(",?");
????}
????writefln("");
????d.length?=?4;
????foreach(inout?int?i;?c){
????????writef(&i);
????????writef(",?");
????}
????writefln("");
????foreach(inout?int?i;?d){
????????writef(&i);
????????writef(",?");
????}
????writefln("");
}
在執行int[] d = c;以后,d的確是和c共享了存儲區。不過在改變d的長度以后,它就和c分道揚鑣了。所以int[] d = c不能理解為d是一個指向c的引用,它實際上創建了一個新的數組對象,但并不拷貝數組元素,它和int[] d = c[0 .. length]是等價的,都是數組切片操作。
這個問題讓我困惑不已。比如你用char[]表示一個單詞,用char[][]表示一行,char[][][]表示多行。如何引用這個單詞?你當然可以每次使用lines[i][j],但如果處理步驟很多,這會不會看起來很頭大?
看上去應該這樣使用:
char[][][]?lines;
char[][]?line?=?lines[0];
line.length?=?line.length?+?1;
line[length?-?1]?=?",";
可惜根據前面的結論,這將無法影響到lines。如果找不到一個引用類型指向數組,有時候使用起來還真是很麻煩??雌饋戆袻ine/Word包裝成類是個勉強湊合的主意。。。