Programmer's Note

コード読み書きの備忘録。

Swiftで関数の配列をつくる

Cでも関数のポインターの配列というのをつくれるが、Swiftでどう書くか試してみる。

もっとも単純なもの:

func func1() {
    println("Hello 1")
}
func func2() {
    println("Hello 2")
}

let fa:[()->Void] = [func1, func2]

fa[0]()
fa[1]()

これはうまく行った。

結果は:

Hello 1
Hello 2

しかし、関数の宣言の場所を変えて、配列の宣言の後にすると、エラーが起きる。

コード:

let fa:[()->Void] = [func1, func2]

func func1() {
    println("Hello 1")
}
func func2() {
    println("Hello 2")
}

fa[0]()
fa[1]()
コンパイルエラー:

:2:22: error: use of unresolved identifier 'func1'
let fa:[()->Void] = [func1, func2]
^
:2:29: error: use of unresolved identifier 'func2'
let fa:[()->Void] = [func1, func2]
^


配列から関数を参照する場合は、定義を先に記述する必要があるってか。
これでは使えない。制約が強い・・・。
ググってみると、クラスのgetterとして定義するやり方を見つけた。

コード:

class AA {
    var fa:[()->Void] {
        return [func1, func2]
    }
    
    func func1() {
        println("Hello 1")
    }
    func func2() {
        println("Hello 2")
    }
    func run() {
        fa[0]()
        fa[1]()
    }
}

let a = AA()
a.run()
結果:

Hello 1
Hello 2


ポイントは、下記のようにgetterとして宣言する。

    var fa:[()->Void] {
        return [func1, func2]
    }

で、これを単に配列宣言しても、

    var fa:[()->Void] = [func1, func2]

、、、うまく行かない。コンパイルエラーになる:
:3:25: error: '()' is not a subtype of 'AA'
var fa:[()->Void] = [func1, func2]


クラスの初期化部分はまだよくわからい・・・。