文字列まわり

まず誤記の訂正。


1/19 と 1/21 に配列の出力は printf でできると書きましたが、std.stdio.writefln の間違いでした。筆者は似たよーなものと思っておりましたが、printf は std.c.stdio のものなので、オブジェクトとは無縁。配列の各要素に対して .toString() を呼び出すなんて気のきいたことはしてくれません。


printf で配列の出力ができると思い込んでいたので、sprintf を使って配列の文字列化ができないものかと試していたのですが、どーもできないのでおかしいなぁとは思っていたのですが…… 今朝方 printf で出力しようとしてみるとできないことにようやく気がつきました。早くも情報の正確性には信頼できない日記となってしまっております(恥)


D言語自体、まだ使っている人は少ないでしょうし、アクセス数見てもたいしたことはないので、マネして被害にあった人はあまりいないとは思いますが(おりませんように)、伏してお詫び、訂正します。


で、昨日の続き。
文字列化関数のテンプレート

template ObjToString(T) {
    char toString(T value) {
        char buffer;
        static      if (is (T : char)) buffer = value;
        else static if (is (T : Object)) buffer = value.toString();
        else                             buffer = std.string.toString(value);
        return buffer;
    }
}

template ArrayToString(T) {
    char toString(T[ ] array) {
        char buffer = "[";
        foreach(T value; array) buffer ~= ObjToString!(T).toString(value) ~ ",";
        buffer = chop(buffer);
        buffer ~= "]";
        return buffer;
    }
}

template MapToString(Key, T) {
    char toString (T[Key] map) {
        char[] buffer = "[";
        foreach(Key key, T value; map) {
            buffer ~= "{";
            buffer ~= ObjToString!(Key).toString(key);
            buffer ~= ":";
            buffer ~= ObjToString!(T  ).toString(value);
            buffer ~= "},";
        }
        buffer = chop(buffer);
        buffer ~= "]";
        return buffer;
    }
}

これでもまだ完璧とは言えず、連想配列の Key と、(連想)配列の Value が配列または連想配列だとダメ。
ObjToString.toString()内の static if 部分で、対象が(連想)配列かどうかの判定ができればよいのだが。


それにしても D って、文字列が char[] であるとはうたっているけど、C風の0終端文字列のことも理解しなければならない局面があったり、ポインターが残っていたりと、Cの余計な部分をまだひきずっている感じ。asm 文があったりするように、ハードに近い部分も細かい処理が可能なようにとの配慮は解るのだが。


やはり文字列周りは、Java の String が清潔で美しいですなぁ。