Swift2[1]: OptionSetType
という訳でDev Forumsへのネタ提供のネタも尽きてきたので、逆提供してもらうことにした。
Swift 2の鳴り物入りの新機能:
- エラーハンドリング
- 可用性チェック
- プロトコル拡張
等々に加え、地味に色んな点が変更になっていて、そこら変でつまづいている人も多い。Xcode7の正式リリースも近づいてるんで、「そろそろうちの社でも本気でSwiftの採用を検討しようか」なんて動きも出ているようなんで、転ばぬ先の杖と言うことでいくつかDev Forumでよく上がっていた失敗例を挙げていこうかと思う。第1回は(うちのBBSの性格上、第2会は無い可能性もあるのであまり期待しないよう)OptionSetTypeから。
こんなコードがSwift2では動かない。
これ、Swift1.xでは、RawOptionSetTypeとしてインポートされていたNS_OPTIONSがOptionSetTypeに変更になったため。Swift2だとこんな書き方になる。
中身が単に整数ビットマスクだとわかっているC寄りのプログラマーにはピンとこないかもしれないが、Swift enumのassociated valueを見て、「これってPascalの可変レコード型だよね」と思った人には、「Pascalのset型じゃん」と思われることだろう。リテラル表記はSwift1.2で導入されたSet型と共通(Array型とも共通ってのがちょっと分かりづらい)。
ちなみに空要素は、Objective-Cでは0、Swift1.xではnil (.allZerosだかなんだかを使っている人も多かったらしい、私は使ったことが無いが)だったのが、空集合(空配列)と同じに[]に変わっちゃったりなんかしている。Xcode7のメソッド呼び出し時のタイプエラーは未だにとんでもない場所を示したりするので、options:引数をnilにしたせいでエラーになっているの見抜けずに、違う場所を試行錯誤で変えまくっている人も多い。まずは、options: nilをoptions: []に変えてみてちょ。
プロトコル拡張はデフォルト実装としても使えるので、自分でコードを書かないといけない部分はRawOptionSetTypeの頃に比べて減ったのだが、それでもまだこんな書き方をしないといけない。
普通要るでしょってvar rawValue: Intをイニシャライザ込みで宣言しないといけないのもうざいが、後半の定数地の宣言もかなりうざい。せめてenumのように、
とか書けるようにならないものか。まだFeature Requestは書いていない。
Swift 2の鳴り物入りの新機能:
- エラーハンドリング
- 可用性チェック
- プロトコル拡張
等々に加え、地味に色んな点が変更になっていて、そこら変でつまづいている人も多い。Xcode7の正式リリースも近づいてるんで、「そろそろうちの社でも本気でSwiftの採用を検討しようか」なんて動きも出ているようなんで、転ばぬ先の杖と言うことでいくつかDev Forumでよく上がっていた失敗例を挙げていこうかと思う。第1回は(うちのBBSの性格上、第2会は無い可能性もあるのであまり期待しないよう)OptionSetTypeから。
こんなコードがSwift2では動かない。
let dateComponentsFormatter = NSDateComponentsFormatter()
dateComponentsFormatter.allowedUnits = NSCalendarUnit.Hour | NSCalendarUnit.Minute | NSCalendarUnit.Second
これ、Swift1.xでは、RawOptionSetTypeとしてインポートされていたNS_OPTIONSがOptionSetTypeに変更になったため。Swift2だとこんな書き方になる。
let dateComponentsFormatter = NSDateComponentsFormatter()
dateComponentsFormatter.allowedUnits = [.Hour, .Minute, .Second]
中身が単に整数ビットマスクだとわかっているC寄りのプログラマーにはピンとこないかもしれないが、Swift enumのassociated valueを見て、「これってPascalの可変レコード型だよね」と思った人には、「Pascalのset型じゃん」と思われることだろう。リテラル表記はSwift1.2で導入されたSet型と共通(Array型とも共通ってのがちょっと分かりづらい)。
ちなみに空要素は、Objective-Cでは0、Swift1.xではnil (.allZerosだかなんだかを使っている人も多かったらしい、私は使ったことが無いが)だったのが、空集合(空配列)と同じに[]に変わっちゃったりなんかしている。Xcode7のメソッド呼び出し時のタイプエラーは未だにとんでもない場所を示したりするので、options:引数をnilにしたせいでエラーになっているの見抜けずに、違う場所を試行錯誤で変えまくっている人も多い。まずは、options: nilをoptions: []に変えてみてちょ。
プロトコル拡張はデフォルト実装としても使えるので、自分でコードを書かないといけない部分はRawOptionSetTypeの頃に比べて減ったのだが、それでもまだこんな書き方をしないといけない。
struct MyOptionSet: OptionSetType {
var rawValue: Int
init(rawValue: Int) {self.rawValue = rawValue}
static let MyOptionA = MyOptionSet(rawValue: 1)
static let MyOptionB = MyOptionSet(rawValue: 2)
static let MyOptionC = MyOptionSet(rawValue: 4)
}
普通要るでしょってvar rawValue: Intをイニシャライザ込みで宣言しないといけないのもうざいが、後半の定数地の宣言もかなりうざい。せめてenumのように、
struct MyOptionSet: OptionSetType {
var rawValue: Int
init(rawValue: Int) {self.rawValue = rawValue}
case MyOptionA = 1
case MyOptionB = 2
case MyOptionC = 4
}
とか書けるようにならないものか。まだFeature Requestは書いていない。