D言語のいろんな機能

細々としたものを細々と載せていきます

#標準エラー出力
標準出力(stdout.writelnやwriteln)は入力とかの後にまとめて出力されてしまいます. 
stderrではその場で出力されます.

```d

stderr.writeln("入力前に出力される");
stdout.writeln("入力後に出力される");
writeln("入力後~~")

char[] hoge = readln().dup;

writeln(hoge);

```

```
[出力]
入力前に出力される
(入力)
入力後に出力される
入力後~~
(入力結果)
```

の順で出力されます

#入力
テキスト入力

```d
import std.file, std.string, std.algorithm, std.array;

//チェインメソッドを使わない処理
string[] text = splitLines(readText("text.txt"));
string[] hoge;

foreach(int i; text){
    hoge[i] = text[i];
}


//最初にデータをすべて読み込んで一気に分割する方法
//対象ファイルが大きいと結構メモリを食うらしい
string[] text2 = splitLines(readText("text.txt")).map!strip.array;

//各行を順々に処理
auto strippedLines = File("text.txt").byLineCopy().map!strip.array;
```

参考: [弱小PHPerのD言語挑戦記4](http://qiita.com/kiridaruma/items/2acd43f9cc505f0eccf1)

キーボード入力

```d
import std.string, std.algorithm, std.array, std.conv;

//char[]型の入力
char[] arr = readln().dup;

//任意の要素をint型に変換して格納
//入力するときはスペースで区切る
//もっといいやり方あるよね...
string[] input = readln().split;
int num = input[0].to!int;

//intの配列に代入
int[] a = readln().split.map!(to!int).array;
```

※readln()について
buf = readln()という形にするよりreadln(buf)のほうが高速らしいです

#二次元配列
int型の二次元配列

```d
//int型の配列
int[3][] arr_i = [[1,2,3],
                  [4,5,6],];

//注意！
//定義の[i][j]は参照では[j][i]になっている！
assert(arr_i[0][2] == 3);

//文字列の配列
char[4][] arr_c = ["abcd",
                   "efgh",];
//これでもok
string[]  arr_s = ["abcd",
                   "efgh",];

arr_c[1][2] = 'i'; //stringではこんなふうにできない
arr_s[0]    = "test"; //これならできる

```

#alias
シンボルに別名を付ける機能.
typedefのようにも使えます.

```
alias myint = int;

void foo(int x) {...}
void foo(myint m) {...} //エラー : foo(int x)と同じ. 
```

#テンプレート

```
template Integer(int nbits)
{
    static if (nbits <= 8)
	alias  byte Integer; //alias Integer = byte と同義
    else static if (nbits <= 16)
	alias short Integer;
    else static if (nbits <= 32)
	alias int Integer;
    else static if (nbits <= 64)
	alias long Integer;
    else
	static assert(0);
}

int main()
{
    Integer!(8) i ;
    Integer!(16) j ;
    Integer!(29) k ;
    Integer!(64) l ;

    assert(i.sizeof == byte.sizeof
	   && j.sizeof == short.sizeof
	   && k.sizeof == int.sizeof
	   && l.sizeof == long.sizeof);
    
    return 0;
}
```

また以下フィボナッチ定数を求める関数テンプレート

```
template Fibonacci(int n)
{
    static if (n >= 2)
	enum Fibonacci = Fibonacci!(n-1) + Fibonacci!(n-2);
    else static if (n == 1)
	enum Fibonacci = 1;
    else static if (n == 0)
	enum Fibonacci = 0;
    else
	static assert(0);
}

void main()
{
    assert(Fibonacci!(10)==55);
}
```

参考:
[公式(日本語訳)](http://www.kmonos.net/alang/d/cpptod.html)

#Appender

```d
import std.array;
import std.algorithm;

void main() {
    auto app = appender!string();
    string b = "abcdefg";
    app.put(b);    
    assert(app.data == "abcdefg");
    assert(app.data[3..5] == "de");

    app.clear(); //配列をクリア

    int[] a = [ 1, 2 ];
    auto app2 = appender(a);
    app2.put(3);
    app2.put([ 4, 5, 6 ]);
    assert(app2.data == [ 1, 2, 3, 4, 5, 6 ]);
    
    //appenderのdataは普通の配列と同じように使えるみたい
    app.data[1..3].bringToFront(app.data[4..6]);
    assert(app.data == [0,4,5,3,1,2,6]);
}
    app ~= [7,8]; //これもOK
    assert(app.data == [0,4,5,3,1,2,6,7,8]);
```

参考:
[D言語友の会](http://dusers.dip.jp/modules/wiki/?SampleCodes%2FPhobos%2Frange%2F2)

#その他
##文字か数字か判断
isNumericがいいね

```d
 //数値にはできないのでfalse
 assert(isNumeric("d3e"))==false);

 //数字列なのでtrue
 assert(isNumeric("123")==true);
```

std.traitsには良さげな機能がたくさんありそうです

##Sleep処理

```d
import core.thread;

 Thread.sleep( dur!("msecs")( 50 ) );  // 50ミリ秒sleep
 Thread.sleep( dur!("seconds")( 5 ) ); // 5秒sleep
```

##時間

```d
import std.stdio;
import std.datetime;
	
void main()
{
	auto t= Clock.currTime();
	writef("%04d-%02d-%02d %02d:%02d:%02d\n"
		,t.year
		,t.month
		,t.day
		,t.hour
		,t.minute
		,t.second);
}
```

参考:
[プログラミング言語サンプル集](http://simplesandsamples.com/date-d.d.html)