Swift Type Eraser is 何?
ググると出てくるやつ
多分 try! Swift 2016で発表があってそれのまとめ記事がよく出てくる。
protocol Pokemon { associatedtype Element var element: Element { get } }
associatedtype を持つProtocolで変数を宣言するとエラーになる。
let pokemon: Pokemon // Protocol 'Pokemon' can only be used as a generic constraint because it has Self or associated type requirements
struct Thunder {} struct Fire {} class Pikachu: Pokemon { var element: Thunder { Thunder() } } class Raichu: Pokemon { var element: Thunder { Thunder() } } class Charmander { var element: Fire { Fire() } }
具体型なら定義できる
let pikachu: Pikachu let raichu: Raichu
でんきタイプのポケモンの配列を定義するにはどうしたらいいか?
class AnyPokemon<PokemonType>: Pokemon { var element: PokemonType init<P: Pokemon>(_ pokemon: P) where P.Element == PokemonType { self.element = pokemon.element } }
let thumderPokemon1: AnyPokemon<Thunder> = AnyPokemon(Pikachu()) let thumderPokemon2: AnyPokemon<Thunder> = AnyPokemon(Raichu())
当たり前という気がするのだが。。
Type Eraserの実装パターン
Closure APIKitのsendメソッドのクロージャーとかも、これに似てるかもしれない。
Box
ライブラリでよく使ってるので参考に
RealmSwift
ReSwfit
protocol AnyPokemon { var _element: Any { get } } protocol Pokemon: AnyPokemon { associatedtype Element var element: Element { get } } extension Pokemon { var _element: Any { element } }
PokemonをAnyPokemonに準拠するという方法
let pokemons: [AnyPokemon] = [Pikachu(), Raichu()]
Carbon
Boxパターンとかいうやつ