2016-02-02 11 views
8

Przewodnik wprowadzający do Julii, Learn Julia in Y Minutes zniechęca użytkowników z ciągów znaków UTF8 indeksowania:Dlaczego indeksowanie ciągów UTF8 jest odradzane w Julii?

# Some strings can be indexed like an array of characters 
"This is a string"[1] # => 'T' # Julia indexes from 1 
# However, this is will not work well for UTF8 strings, 
# so iterating over strings is recommended (map, for loops, etc). 

Dlaczego iteracji po takich ciągów zniechęcać? Co konkretnie na temat struktury tego alternatywnego typu łańcucha sprawia, że ​​błąd indeksowania jest podatny na błędy? Czy jest to pułapka specyficzna dla Julii, czy też dotyczy to wszystkich języków z obsługą ciągów UTF8?

+1

Od UTF-8 jest kodowaniem multi-bajt Unicode, takie rzeczy indeksowania na ciąg znaków UTF-8 lub uzyskanie długość (w znakach, w przeciwieństwie do kodu jednostki) są operacjami O (n) (gdzie n jest rozmiarem łańcucha). Jeśli musisz robić takie rzeczy często, lepiej byłoby używać UTF32String i konwertować do/z UTF8 w razie potrzeby. Nie jest to pułapka specyficzna dla Julii, ale niektóre języki, takie jak Python 3, mogą wybrać najlepszą wewnętrzną reprezentację dla ciągów Unicode, które wciąż są O (1) do indeksowania, w zależności od napisu. –

Odpowiedz

11

Ponieważ w UTF8 znak nie jest zawsze kodowany w jednym bajcie.

Weźmy na przykład ciąg w języku niemieckim böse (zły). bajtów ten ciąg w kodowaniu UTF8 są:

0x62 0xC3 0xB6 0x73 0x65 
b ö   s e 

Jak widać umlaut ö wymaga 2 bajtów.

Teraz, jeśli bezpośrednio zaindeksujesz ten kodowany kod UTF8 "böse"[4] otrzymasz s, a nie e.

Jednakże, można użyć ciągu jako iterowalny obiektu w Julia:

julia> for c in "böse" 
      println(c) 
     end 
b 
ö 
s 
e 

A odkąd poprosił, No, bezpośrednie kwestie bajt ustalające z ciągów UTF8 nie są specyficzne dla Julii.

Zalecenie dla dalszego czytania:
http://docs.julialang.org/en/release-0.4/manual/strings/#unicode-and-utf-8

+2

możesz również iterować używając 'chr2ind', który konwertuje z indeksów bajtowych na indeksy znaków:' dla i in 1: length (s); c = chr2ind (s, i); println (s [c]); koniec'. – amrods

+5

@amrods można użyć funkcji 'grafemes' zamiast:' collect (grafhemes ("böse")) 'zwraca' ["b", "ö", "s", "e"] ' – SalchiPapa

+0

@ismael bardzo miło know ... thanks – amrods