swiftのローカルスコープ

色々と試して出来ないのかと、諦めていた。 が、ググると stackOverFlowのサイトに答が有った。

http://stackoverflow.com/questions/24011271/how-to-create-local-scopes-in-swift

こーやって、locallyを定義すると。

func locally(work: () -> ()) {
    work()
}

こんな風に、使える。

locally {
    let g = 42
    println(g)
}

swiftでは引数の最後の引数は括弧の外にだしても良いようだ。

色々と、試してみるとこんな感じ。

func local(test:Int, inWork:()->())
{
    inWork();
}

// OK
local(12,
    {

    })

// OK
local(12){

}

// Error
local(12)
{

}

3番目の例が文法的に許さないのは、単純なローカルスコープと引数の区別が出来ないのかも知れない。

swiftでは@synchronizedはサポートが無いそうなので、このローカルスコープを作る方法を利用出来そうだと思った。 が、これもまた、ググると stackOverFlowのサイトに答が有った。

http://stackoverflow.com/questions/24045895/what-is-the-swift-equivalent-to-objective-cs-synchronized

func synced(lock: AnyObject, closure: () -> ()) {
    objc_sync_enter(lock)
    closure()
    objc_sync_exit(lock)
}

synced(self) {
    println("This is a synchronized closure")
}

この、クロージャーを受け取って、その前後で定型処理を行うのは結構つかえるテクニックに見える。 例えば、

func cgLoclaContext(closure: () -> ()) {
    var theContext: CGContext;
    CGContextSaveGState(theContext)
    closure()
    CGContextRestoreGState(theContext)
}

cgLoclaContext() {
    // ココで、描画色を変えたり、クリッピングリージョンを変えたりする。
}
// ここまでくると、CGContextの状態が自動で戻る。

ローカルスコープと、CoreGraphixの状態を一致させる事で状態の戻し忘れ等のミスを防げそう。