2015年1月1日木曜日

Optional

Swift で注意を引くのが Optional type だ (「オプション型」とか「オプショナル型」とかの訳がある)。大雑把にいえば、当該の型と nil を合わせたものというイメージで、文字列を例にとれば、たとえば文字列を返すべき関数がうまく値を返せないときに nil を返すようにすることができる。しかし Swift は型にうるさい言語だから、ときに文字列ときに nil (これは文字列型ではない) を返すような関数は書けない。なので文字列と nil を含んだ型を使うことになる。ただし、これは単純な文字列型とは異なるので、扱い方も多少ことなる。対話環境で確認してみる。

  1> var a:String = "a" /* String */
a: String = "a"
  2> var b:String? = "b" /* Optional */
b: String? = "b"
  3> println(a)
a
  4> println(b)
Optional("b")
  5> println(b!)
b
  6> a = nil
repl.swift:6:5: error: type 'String' does not conform to protocol 'NilLiteralConvertible'
a = nil
    ^

  6> b = nil
  7>7 b
$R0: String? = nil

オプション型の変数を宣言するときは ? を付ける。変数をそのまま印字すると、文字列そのものではなくて Optional("b") が出力される。文字列を取り出すには ! を付ける必要がある。文字列型の変数 a には nil を代入することはできないが、オプション型の b には代入できる。面倒くさい? 確かに。僕はこの概念には Ocaml で触れて少しは慣れているので有り難みも分かるが、区別の必要があるしタイプ量も増えるので、特に初めての人は面倒に感じるだろう。Swift の開発者もそう思ったのか、! を使わなくても比較演算子が使えたり、nil のチェックを条件にできる if-let 構文が用意されたりしている。ただ、これは痛し痒しで、簡単になる部分もあるが覚えるべきことが増えるという面もある。僕は今回オプション型が直接 == で比較できることを知らずに使ってしまい (つまり文字列のつもりで比較しようとして)、それでもエラーにならないので戸惑った。一方 if-let は nil チェックと unwrap を同時にやってくれる秀逸な構文だと思う。比較演算子と違って、文脈を見ないとどういう型を扱っているのか分からないというようなこともない。他にも使い所の決まった便利な書き方があるようだが、それが学習を複雑化しないことを願うのみだ。

さて、今までずっと「オプション型」という言い方をしてきた。最初に言ったように Optional type の訳で、この optional は名詞だ。それを素直にカタカナ化すれば「オプショナル」ということになる。「オプション」は optional の日本語訳の可能性としてあるだろうか? 意味を考えれば「nil化可型」とか (nullable type といういい方もあるらしい)、「データがないかもしれない型」とか (Haskell では Maybe という型があるらしい)、使えそうにない名前が思い浮かぶ。僕が「オプション」と言っているのは、多分 Ocaml が option と言っている影響だろう。あとは、日本語の名詞として「オプショナル」に馴染みがないからか。まあ、誰かが決めてくれれば良い。

本題から外れるが、これを書いているあいだ何度も「オプチョン」と入力しては消していた。僕はいわゆる訓令式でローマ字入力しているので sy と打たなければならないところを ty と打ってしまうわけだ。もちろん英語の綴りに引きずられた結果だから、こういう目に合うとかな入力擁護派の主張ももっともだと思えてくる。今年の目標としてかな入力に習熟するというのを立ててみようかな。