LoginSignup
8
3

More than 5 years have passed since last update.

Julia その2 文字列関係

Posted at

文字列と文字

Juliaでは文字列リテラルはダブルクォートで、文字リテラルはシングルクォートで書く。それぞれの型はStringCharだ。
この辺は、CやJavaなどと同じで、Pythonのように、どちらも文字列で適当に使い分ける、というようにはなっていない。

julia> typeof("test")
String
julia> typeof('t')
Char

StringCharも、Unicodeを表現する事ができる。ただし、Charは個別のUnicodeポイントを表現しているのに対して、StringはUTF-8エンコードされたバイト列を格納している。StringCharの配列ではないことに注意する必要がある。このあたりはRustも同じ。

文字列リテラルには任意のUnicode文字列がそのまま使える。関数lengthでUnicode文字列としての長さを得ることができる。

julia> s = "てすと"
"てすと"
julia> length(s)
3

文字列の結合と繰り返し

文字列の結合は、まあどんな言語にも用意されていて、普通は+演算子を使う。JavaもPythonもそうだ。が、Juliaではなぜか*演算子を使う。

julia> "abc" + "def"
ERROR: MethodError: no method matching +(::String, ::String)

julia> "abc" * "def"
"abcdef"

文字列を複製して繰り返す演算もいくつかの言語に用意されているが、普通はこちらに*を使う。Juliaではなんとべき乗の演算子である^を使う。

julia> "abc" ^ 3
"abcabcabc"

なんでだ。どこから来たんだこの言語仕様。。。

Unicode文字列のインデックス

ここからがちょっと胡散臭い。文字列は配列のようにアクセスできるのだけど、その時のアクセスはバイト単位のインデックスとなる。
UTF-8エンコードは1文字が1バイトから4バイトまでの可変長表現なのでバイト単位でインデックスすると、そこが正しい文字境界である保証がない。
なので、エラーが起こる。。

julia> s[1]
'て': Unicode U+3066 (category Lo: Letter, other)
julia> s[2]
ERROR: StringIndexError("てすと", 2)

有効なインデックスを取得するにはnextindex関数を用いる。最初と最後の有効なインデックスはそれぞれfistindex, lastindexで得られるので次のようにすると一文字ずつ取り出すことができる。面倒臭すぎる。

julia> function pick1by1(s)
           index = firstindex(s)
           while index <= lastindex(s)
               println(s[index])
               index = nextind(s, index)
           end
       end
pick1by1 (generic function with 1 method)

julia> pick1by1(s)
て
す
と

所感

文字列のUnicode対応はいろいろ面倒。かつてJavaはcharを16bitにしてみなを驚かせたが、その後Unicodeが16bitでは足りなくなって、身動き取れなくなっているようだ。どうすんだあれ。

一般に、Unicode文字列への対応方法としては 1) 1文字に3-4バイト割り当てて、文字の配列として保持する 2) UTF-8 などのエンコードにしてバイト列で保持する、の2択。

Python3は前者、Rust、Juliaは後者になっている。前者だとascii文字のみを格納する場合にデータ量が4倍になる。Rustのような性能命の言語ではこれは致命傷なので、後者を選択するのは妥当だと思うのだけど、Juliaのようなエンドユーザ向けの言語では、前者のほうが良かったんじゃないのかなあ。。

8
3
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
3