我想了解如何使用std.container中可用的各種容器結構,但我無法理解如何執行以下操作:D:不清楚如何使用std.container結構
1)如何創建一個空容器?例如,假設我有一個用戶定義的類Foo
,並且想要創建一個應該包含Foo
對象的空DList。我應該使用什麼語法?
2)假設a
和b
都是DList!int
。我嘗試撥打a ~ b
,編譯器告訴我我不行。但是,我可以看到DList
已重載該運算符。我錯過了什麼?
我想了解如何使用std.container中可用的各種容器結構,但我無法理解如何執行以下操作:D:不清楚如何使用std.container結構
1)如何創建一個空容器?例如,假設我有一個用戶定義的類Foo
,並且想要創建一個應該包含Foo
對象的空DList。我應該使用什麼語法?
2)假設a
和b
都是DList!int
。我嘗試撥打a ~ b
,編譯器告訴我我不行。但是,我可以看到DList
已重載該運算符。我錯過了什麼?
有三種方法來創建一個新的容器,
統一的方式,使用std.container.make
:
auto list1 = make!(DList!int)();
auto list2 = make!(DList!int)(1, 2);
使用結構初始化語法:
auto list1 = DList!int();
使用類的幫助函數:
auto tree1 = redBlackTree!int();
auto tree2 = redBlackTree!int(1, 2);
那些之間的區別是,一些數據結構使用的類和一些與結構實現。並且使用make
,您不需要知道第一種方式,因爲沒有有效的區別。
關於追加操作符,您需要附加從DList!T
開始的範圍,而不是DList!T
本身。例如:
上使用一個更完整的例子,檢查以下內容:
import std.container;
import std.stdio;
class Foo {
int i;
this(int i) {
this.i = i;
}
void toString(scope void delegate(const(char)[]) sink) const {
// this is a non allocating version of toString
// you can use a normal `string toString()` function too
import std.string : format;
sink("Foo: %s".format(i));
}
}
void main() {
auto odds = make!(DList!Foo)();
odds.insert(new Foo(3));
odds.insert(new Foo(5));
writeln("Odds: ", odds[]);
odds.insertFront(new Foo(1));
writeln("Odds: ", odds[]);
auto evens = make!(DList!Foo)();
evens.insert(new Foo(2));
evens.insert(new Foo(4));
writeln("Evens: ", evens[]);
odds.insert(evens[]);
writeln("Odds then evens: ", odds[]);
odds ~= evens[];
writeln("Odds then evens x 2: ", odds[]);
}
可以運行這個網上瀏覽:http://dpaste.dzfl.pl/f34b2ec8a445
a ~ b
那麼容易。首先,你需要做切片了出來,然後你需要使用~=
運營商,所以a ~ b
成爲a ~= b
下面是一些代碼:
import std.stdio;
import std.container;
class Foo {
private int _val;
public this(int arg) { _val = arg; }
public int val() @property { return _val; }
public void val(int arg) @property { _val = arg; }
}
int main() {
auto foos = DList!Foo();
auto a = DList!Foo();
a.insert(new Foo(5));
auto b = DList!Foo();
b.insert(new Foo(11));
foos ~= a[]; // slice
foos ~= b[]; // slice
// writeln(foos[0].val); // "Error: no [] operator overload for type DList!(Foo)"
writeln(foos.front.val); // prints 5
writeln(foos.back.val); // prints 11
return 0;
}
在我的愚見,DLIST肯定需要改進。 - 例如,你無法獲得它的長度! (沒有評論)如果你看看http://dlang.org/phobos/std_container.html,它清楚地表明容器原語應該有length屬性。但是,它沒有說明應該支持a ~ b
!幸運的是,Array!T確實如此。同樣,std.container頁面也聲明c [x]也應該被支持(其中c是一個容器類型)。就DList!而言,它根本行不通。
我虛心地建議你使用Array而不是DList。它應該表現得更好(更容易緩存),它擁有我們真正需要的一切,包括上面提到的長度屬性。
讓我們修改代碼以使用Array:
import std.stdio;
import std.container;
class Foo {
private int _val;
public this(int arg) { _val = arg; }
public int val() @property { return _val; }
public void val(int arg) @property { _val = arg; }
}
int main() {
auto foos = Array!Foo();
auto a = Array!Foo();
a.insert(new Foo(5));
auto b = Array!Foo();
b.insert(new Foo(11));
foos = a ~ b; // concatenation works, ah joy! :)
writeln(foos[0].val); // indexed access! yeah! prints 5
writeln(foos[1].val); // prints 11
// Lets the user press <Return> before program returns
stdin.readln();
return 0;
}
編輯:在IRC上最近的討論提供了一個啓示 - DLIST沒有一定的操作(如索引訪問的),因爲該操作將不能滿足最低的複雜性要求(在std.container網頁上列出)。
如何從std.container數組中刪除元素?就像說最後一個?當我嘗試std.algorithm.remove或linearRemove時,我得到編譯器錯誤。 – AbstractDissonance