LoginSignup
7
7

More than 5 years have passed since last update.

Control Structure with Extension

Last updated at Posted at 2014-06-14

Swiftを調べていて一番感動したのがこのFeature。既存のクラスにたいていExtensionという仕組みを使うと自分なりに拡張することができる。

struct SampleStruct {
    var v: Int = 0
    init(v: Int) {
        self.v = v
    }
}

extension SampleStruct {
    mutating func mulFactor(factor: Int) {
        v *= factor
    }
}

既存のstruct SampleStructとその拡張を用意する。
そうするとmulFactorはクライアントコードから呼び出すことができる。

var s: SampleStruct = SampleStruct(v: 5)
s.mulFactor(10)
println(s.v) // -> 50

今回はSampleStruct本体を自分で定義したから別に面白くないけれど、これが他人の書いたクラスだったらどうだろう。例えばInt

extension Int {
    func repetition(task: () -> ()) {
        for i in 0..self {
            task()
        }
    }
}

こんな拡張を書いてあげるとこれはIntのメソッドとして使うことができる。

100.repetition({ println("Hello, World")})
// Hello, World
// Hello, World
// Hello, World
// Hello, World
// ... 100個続く

Swiftでは評価部分だけのClosureは丸括弧を省いていいので以下のようにも書ける。

100.repetition{
   println("Hello, World")
}

制御構造のようにも見える。ExtensionとClosureを使えばScalaのように自由にDSLも書ける!

ちなみにひとつハマったのは

Classに対してはmutating宣言されたExtensionを書くことができない。先ほどの例だとこんか感じ。

class SampleClass {  // <-- ここがクラス
    var v: Int = 0
    init(v: Int) {
        self.v = v
    }
}

extension SampleClass {
    mutating func mulFactor(factor: Int) {  // <-- ここでコンパイラに怒られる
        v *= factor
    }
}

'mutating' isn't valid on methods in classes...

とか言われるのでダメっぽい。

7
7
0

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
7
7