[D]
D言語の学習
最近ちょっとD言語を触りだした。C++よりはめんどくさくなく、コンパイル時間が短そうだからだ。
学習リソース
- あんまりないぞ。みんなゲーム作ってる。
公式サイト
その他
- 基本文法と頻出のアルゴリズム
- たまに使うかもな文法
- Idioms for the D Programming Language ・・・ D言語で使うことのできるイディオム集
- Java 8を関数型っぽく使うためのおまじないをD言語でやってみた … 関数型言語的操作
オンラインコンパイラサービス
C++との比較
連想配列 => std::map 的な
ここの受け売り
int[string] m; m["one"] = 1; m["two"] = 2; m["three"] = 3; if( "four" in m ) writeln("hogehoge"); m.remove("three"); writeln(m.length); // 2 foreach(key, value; m) { ... } int[string] point_to_same_as_m = m; // 同じmapを参照 int[string] another = m.dup; // コピーはdupで
- 言語機能に組み込まれているので、ちょっと物足りない
データ構造 => std::pair, std::tuple 的な
import std.typecons; void main() { Tuple!(int, string, real) t = tuple(1, "hello", 3.14); // tuple() 関数はC++のmake_pairみたいなもの、型を省略して構築 int x = t[0]; // 0番目はint string y = t[1]; // 1番目はstring t[2] = 2.72; // 2番目はreal }
- Tupleの宣言だけ気に入らない(小文字がいい)
コレクション操作 => Scalaのmap, filter, foreach 的な
ここから
import std.algorithm; auto arr = [1, 2, 3, 4, 5]; // 条件に合うものだけを選ぶ filter!("a % 2 == 0")(arr); // [2, 4] // '"a % 2 == 0"'の代わりに'a => a % 2 == 0'でもOK.delegateと文字列両方受け付ける filter!(a => a % 2 == 0)(arr); // [2, 4] // 条件に合うものを除く remove!("a % 2 == 0")(arr); // [1, 3, 5] // 加工結果をRangeで返す map!("a * a")(arr); // [1, 4, 9, 16, 25] // 降順にソートする sort!("a > b")(arr); // [5, 4, 3, 2, 1]
- やっぱこれがないとダメだ
- コレクションの連結でデータを加工する処理ももちろん書ける、ただしちょっと制限が多いかな?
匿名関数・関数合成・カリー化 => さらに関数型言語的な操作
ここを見よう
- 関数合成は使いたい
参照渡し
- D言語には参照渡しがない?
- → ありました。 ref パラメーターがその役割を果たしている。
- ref関数
- ref関数は、返値を参照で返します。 ref引数の返値バージョンです。
ref int foo() { auto p = new int; return *p; } ... foo() = 3; // ref返値は左辺値となる
- つまりref使わないとすべてのデータがディープコピーされる?(未確認)
暗黙的な記法の比較
主に、ここが参考になった gchatelet / dlang_cpp
C++での記法 | D言語での記法 | 意味 |
---|---|---|
&T | ref T | Tの参照 |
const &T | ref const(T) | const Tの参照 |
*T | T* | Tのポインタ |
const *T | const(T*) | const Tのポインタ |
上記は関数の返り値の型を表記する際の記法で、関数の引数の場合はconst(T)ではなく、 const Tと書けばよさそう。なぜそうなっているのかはわからない。
templateの継承、コンストラクタ/デストラクタの操作
- D言語には templateの継承がない(→ mixinを使ったほうがいいこともある)
- → クラスの形にすれば大丈夫
- D言語にはtemplateでのコンストラクタ/デストラクタの使用ができない
- → これもクラスの形にすればOK
template (T) { class child : parent { public: this() { } ~this() { } } }
機能として存在しないもの
- D言語には inline functionがない
- 予約語としては存在するが実装はないとか
- D言語には初期化子、つまり Constructors and member initializer lists がない
- C++の場合、クラスのコンストラクタでメンバ変数を初期化する機能がある
- Zachary Lund
- January 31, 2012
In C++, they provide a mechanism to initialize class variables to a passed value.
C++にはクラス変数を通すことで変数を初期化する機構があります。
class Test { int bob; public: Test(int jessica) : bob(jessica) { } };
The above basically says "int this.bob = jessica;" as opposed to this:
上記は、
class Test { int bob; public: Test(int jessica) { bob = jessica; } };
which basically says "int this.bob = void; bob = jessica;". Now, I'm not a speed freak but this is a quick and should be a painless optimization. D allows defaults set by the class but cannot seem to find anything to allow me variable initialization values. Not that it's that big of a deal but am I missing something?