2012-09-05 13 views
7

próbuję skompilować następujący kod:std.algorithm.joiner (string [], string) - dlaczego elementy wynikowe są dchar a nie char?

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 
} 

Kompilacja z dmd kończy się błędem:

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

Zmiana char z do dchar z ma rozwiązać komunikat o błędzie, ale jestem zainteresowany, dlaczego pojawia się w pierwsze miejsce.

Dlaczego wynik joiner(string[],string).front() jest dchar i nie char?

(Nie ma nic na ten temat w dokumentacji http://dlang.org/phobos/std_algorithm.html#joiner)

Odpowiedz

11

Wszystkie struny są traktowane jako zakresach dchar. Dzieje się tak dlatego, że gwarantowane jest dchar jako pojedynczy punkt kodowy, ponieważ w UTF-32 każda jednostka kodowa jest punktem kodowym, podczas gdy w UTF-8 (char) i UTF-16 (wchar), liczba jednostek kodowych na kod punkt zmienia się. Tak więc, jeśli działałeś na pojedynczych char s lub wchar s, działałbyś na fragmentach znaków, a nie całych postaciach, co byłoby bardzo złe. Jeśli nie wiesz zbyt wiele na temat Unicode, radzę przeczytać książkę Joel Spolsky: this article. Wyjaśnia to całkiem dobrze.

W każdym razie, ponieważ działa na poszczególnych char s oraz wchar s nie ma sensu, ciągi char i wchar są traktowane jako zakresach dchar (ElementType!string jest dchar), co oznacza, że ​​jeśli chodzi o zakresy dotyczą one nie mają length (hasLength!string jest false - walkLength musi być używane, aby ich długość), nie są sliceable (hasSlicing!string jest false) i nie są indeksowane (isRandomAccess!string jest false). Oznacza to również, że wszystko, co tworzy nowy zakres od dowolnego rodzaju, da w wyniku zakres dchar. joiner jest jednym z nich. Istnieją pewne funkcje, które rozumieją kody Unicode i specjalne przypadki dla efektywności, wykorzystując długość, cięcie i indeksowanie, gdzie tylko mogą, ale jeśli ich wynik nie jest ostatecznie fragmentem oryginału, każdy z nich musi zostać wykonany z dchar s.

Tak więc, front w dowolnym zakresie znaków będzie zawsze dchar, a popFront zawsze wyskoczy z pełnego punktu kodowego.

Jeśli nie wiesz zbyt wiele o zakresach, radzę przeczytać this. Jest to rozdział książki o D, która jest w Internecie i jest obecnie najlepszym tutorialem dotyczącym zakresów, które mamy. Naprawdę powinniśmy uzyskać odpowiedni artykuł na temat zakresów (w tym na temat ich działania z ciągami) na dlang.org, ale nikt już nie napisał tego jeszcze. Bez względu na to, będziesz potrzebował mieć przynajmniej podstawową znajomość zakresów, aby móc korzystać z wielu standardowych bibliotek D (szczególnie std.algorithm), ponieważ używa ich bardzo mocno.

Powiązane problemy