序
Infinite loop in getterという記事をみて、カウンタクラス(整数を順番にかえすだけのクラス)を作ってみたくなったので作ってみた。
正攻法
とりあえず、正攻法で以下のように書いた。
Counter.swift
class BaseCounter {
var __counter = 0
var counter: Int {
get {
return __counter++
}
}
}
let c = BaseCounter()
println(c.counter)
println(c.counter)
println(c.counter)
println(c.counter)
まあそれなりに動くのだが、
c.__counter = 0
とか、カウンタの値を外側から直接書き換えられるのがイマイチ。
(privateとか出来ないのかな…?)
クロージャ
そこで、クロージャ(関数閉包)を使って書き換えてみたのが以下。
Counter.swift(その2)
class Counter {
func CountUp() -> (() -> Int) {
var count = 0
func c() -> Int {
return count++
}
return c;
}
let f : (() -> Int)?
init(){
f = CountUp()
}
var counter : Int {
get {
return f!()
}
}
}
let c = Counter()
println(c.counter)
println(c.counter)
println(c.counter)
println(c.counter)
println(c.counter)
これでも、
c.f!()
のように、クロージャに直接アクセスは可能だが、カウンタをゼロに戻すことは出来ないからいい……ことにしておく。
追記:無名関数
どうにかして、もっと短くかけないか頑張ってみた。
無名関数の後ろに()をつけられることに気づいたので、ちょっと短くできた。
Counter.swift(その3)
class Counter {
let f = { () -> (() -> Int) in
var count = 0
func c() -> Int {
return count++
}
return c;
}()
var counter : Int {
get {
return f()
}
}
}
let c = Counter()
println(c.counter)
println(c.counter)
println(c.counter)
println(c.counter)
println(c.counter)