Swift 2.0で追加されたOptionSetTypeがなかなか便利
記事内に広告を含む場合があります。記事内で紹介する商品を購入することで、当サイトに売り上げの一部が還元されることがあります。
Swift 2.0で追加されたOptionSetTypeプロトコルがなかなか便利なので紹介したいと思います!
Swift 1.2までの記述方法
例えば、SpriteKitのカテゴリビットマスクや衝突テストビットマスクなどを設定する場合、Swift 1.2までは以下のように書くことができました。
let redBallCategory : UInt32 = 0x1 << 0 let blueBallCategory : UInt32 = 0x1 << 1 let wallCategory : UInt32 = 0x1 << 2 ballNode.physicsBody?.categoryBitMask = redBallCategory ballNode.physicsBody?.contactTestBitMask = blueBallCategory | wallCategory
典型的なビットマスクの使い方ですね。
あるいは以下のようにstructを使って意味的にまとめて書くこともできました。
struct Category { static let RedBall : UInt32 = 0x1 << 0 static let BlueBall : UInt32 = 0x1 << 1 static let Wall : UInt32 = 0x1 << 2 } ballNode.physicsBody?.categoryBitMask = Category.RedBall ballNode.physicsBody?.contactTestBitMask = Category.BlueBall | Category.Wall
Swift 2.0のOptionSetTypeを使う
Swift 2.0で追加されたOptionSetTypeを使うと、以下のように記述できます。
struct Category : OptionSetType { let rawValue : UInt32 static let RedBall = Category(rawValue: 0x1 << 0) static let BlueBall = Category(rawValue: 0x1 << 1) static let Wall = Category(rawValue: 0x1 << 2) } ballNode.physicsBody?.categoryBitMask = Category.RedBall.rawValue ballNode.physicsBody?.contactTestBitMask = Category([.BlueBall, .Wall]).rawValue
このケースだと、「structを使うのに比べて、書くのが面倒になってない?」とも思えますが、
こんな感じで複数を含むグループを手軽に作れたりします。
struct Category : OptionSetType { let rawValue : UInt32 static let RedBall = Category(rawValue: 0x1 << 0) static let BlueBall = Category(rawValue: 0x1 << 1) static let Wall = Category(rawValue: 0x1 << 2) static let Balls = Category([RedBall, BlueBall]) }
ちなみに上記の
Category([RedBall, BlueBall])
は、SetAlgebraTypeプロトコルで用意されている
init< S : SequenceType where S.Generator.Element == Element>(_ sequence: S)
というイニシャライザを使っているみたいです。OptionSetTypeプロトコルはSetAlgebraTypeプロトコルに適合しています。
また、2つを合成したグループを動的に作成できたり、
var r1 : Category = Category.Balls.union(Category.Wall)
特定の要素を含んでいるかどうかをチェックできるメソッドcontainsが使えたり、
if r1.contains(Category.RedBall) { // do something }
特定の要素を追加・削除できるremove/insertのようなメソッドを使えます。
r1.remove(Category.RedBall) r1.insert(Category.RedBall)
詳しくは以下のリファレンスをチェックしてみてください(OptionSetTypeプロトコルは、SetAlgebraTypeプロトコルに適合しています)。
@akio0911はこう思った。
SetAlgebraTypeプロトコルのメソッド群が強力なので、うまく使えばコードをスッキリとさせることができそうです。


関連記事
この記事が気に入ったら「いいね!」しよう
Twitterで更新情報をゲット!