Swiftのindirectについて調べてみた

  • 27
    いいね
  • 0
    コメント
この記事は最終更新日から1年以上が経過しています。

Swiftの indirect について調べてみました。

indirect とは

Swift2.0から登場(正確にはXcode7 β4かららしい)。enumにくっつけて使うと再帰的なenumを作ることができる。

enum Sample {
    case Some(Sample)   //ここで再帰している
}

と書こうとすると、 indirect enum Sample にするよう指摘してくれる。 indirect case Some(Sample) でも可

indirect の用途

公式ドキュメント的にはThe Swift Programming Language: Enumerations
Recursive Enumerations
に書いてある。題材は (5 + 4) * 2 のような Int と足し算と割り算の3つの要素を enum を使って表すというもの。

要は enumindirect を使うと二分木とかリストとか作れる

なぜ indirect とつけなければいけないのか

enum 自体は値型( String とか Structure とかの類)で再帰ができないため。らしい。 indirect が使えないβ3以前で二分木を作ろうとすると、再帰ができないので1つの enum で表現することができず、複数の enum を用意する必要がある。

参考:
A persistent tree using indirect enums in Swift | Airspeed Velocity
Swift1.2時代のやり方との比較をされている記事:
http://qiita.com/satoshia/items/9c6465356e2e155cd078

おまけその1: indirectsizeof

indirect で再帰が発生するとサイズがちいさくなる。

enum Sample<T> {
    case Foo(T)
    case Bar(T)
}

indirect enum Sample1<T> {
    case Foo(T)
    case Bar(T)
}

enum Sample2<T> {
    indirect case Foo(T)
    case Bar(T)
}

enum Sample3<T> {
    indirect case Foo(T)
    indirect case Bar(T)
}
sizeof() T = Int T = String
Sample 9 25
Sample1 8 8
Sample2 9 25
Sample3 8 8

おまけその2: case バグ

http://qiita.com/satoshia/items/9c6465356e2e155cd078 でも紹介されているが、 if case let hoge = .Some(...) { ... } といった具合に switch 文以外でcaseを使うとクラッシュするらしい。
β5では解消されている模様

参考:
https://forums.developer.apple.com/thread/12188