7

次のコードをコンパイルしようとします:

import std.algorithm;
void main()
{
    string[] x = ["ab", "cd", "ef"]; // 'string' is same as 'immutable(char)[]'
    string space = " ";
    char z = joiner( x, space ).front(); // error
}

dmdエラーで終了するコンパイル:

 test.d(8): Error: cannot implicitly convert expression (joiner(x,space).front()) of type dchar to char

に変更char zするdchar zとエラーメッセージは修正されますが、そもそもなぜ表示されるのか興味があります。

joiner(string[],string).front()の結果がchar ではなく dcharであるのはなぜですか?

(ドキュメントhttp://dlang.org/phobos/std_algorithm.html#joinerには何もありません)

4

1 に答える 1

11

すべての文字列は の範囲として扱われますdchar。これdcharは、a が単一のコード ポイントであることが保証されているためです。UTF-32 ではすべてのコード単位がコード ポイントであるのに対し、UTF-8 ( char) および UTF-16 ( wchar) ではコード ポイントごとのコード単位の数が異なるためです。したがって、個々charの やを操作している場合wcharは、文字全体ではなく文字の一部を操作することになり、非常に悪い結果になります。Unicode についてよく知らない場合は、Joel Spolsky によるこの記事を読むことをお勧めします。それは物事をかなりうまく説明しています。

いずれにせよ、個々charの および を操作するwcharのは意味がないため、charおよびの文字列は( is )wcharの範囲として扱われます。つまり、範囲に関する限り、( is -を使用する必要があります。長さを取得する)、スライス可能ではありません ( is )、およびインデックス可能ではありません ( is )。これはまた、あらゆる種類の文字列から新しい範囲を構築するものはすべて、.dcharElementType!stringdcharlengthhasLength!stringfalsewalkLengthhasSlicing!stringfalseisRandomAccess!stringfalsedcharjoinerその一つです。Unicode と特殊なケースの文字列を効率的に解釈し、可能な場合は長さ、スライス、およびインデックス付けを利用する関数がいくつかありますが、それらの結果が最終的に元のスライスでない限り、それらが返す範囲は作成する必要がありますsのdchar

そのためfront、どの範囲の文字でも常に でありdcharpopFront常に完全なコード ポイントから飛び出します。

範囲についてあまり知らない場合は、これを読むことをお勧めします。これは、オンラインの D に関する本の章であり、現在私たちが持っている範囲に関する最高のチュートリアルです。範囲に関する適切な記事 (文字列の操作方法を含む) をdlang.orgに掲載する必要がありますが、まだ誰もそれを書いていません。とにかく、多くの D の標準ライブラリ (特に std.algorithm) を使用できるようにするには、少なくとも範囲の基本的な把握が必要になります。

于 2012-09-05T20:20:00.457 に答える