LoginSignup
8
4

More than 3 years have passed since last update.

Generics or Protocol associated type? それが問題だ🤔

Last updated at Posted at 2019-06-30

はじめに

「Swiftでは、任意の型に対応させられるように、Genericsを使って型を抽象化できるのか。。。🧐」
「なんと、Protocolでもassosiated typeで任意の型を表現できるらしい!😳」

「。。。。。。。。。。。。。」

「で、どっち使えばいいんだ?🙄🙄」

※以下 PAT = Protocol associated type

検証 (Swift5, Xcode10.2.1)

例えば下記のようにポケモン(もはや恒例)を表す Pokemon というプロトコルとそれに準拠した Pikachu があるとする。
今回はポケモンの名前を出力してくれる PokemonDescriptor を作りたい。
PokemonDescriptor は、Pokemon プロトコルに準拠しているものなら何でも出力できる。

protocol Pokemon {
    var name: String { get }
}

struct Pikachu: Pokemon {
    let name: String
}

PATを使った場合

protocol CharacterDescribable {
    associatedtype Character
    func describe(_ character: Character)
}

struct PokemonDescriptor: CharacterDescribable {
    typealias Character = Pokemon
    func describe(_ character: Character) {
        print("\(character.name)だよ〜")
    }
}

let pikachu = Pikachu(name: "ピカチュウ")

let pokeDescriptor = PokemonDescriptor()

pokeDescriptor.describe(pikachu)

// output: ピカチュウだよ〜

Genericsを使った場合

struct PokemonDescriptor {
    func describe<T: Pokemon>(_ pokemon: T) {
        print("\(pokemon.name)だよ〜")
    }
}

let pikachu = Pikachu(name: "ピカチュウ")

let pokeDescriptor = PokemonDescriptor()

pokeDescriptor.describe(pikachu)

// output: ピカチュウだよ〜

何が違うのか💡

プログラム自体がしていることは同じ。
違いはそれぞれの describe() メソッドが実行される方法(Method dispatch)。

Method dispatchとは
メソッドを呼び出すときにどの実装が実行されるかを選択/解決するシステム。
コンパイラがコンパイル時にそれを解決するのがstatic dispatch。実行時に解決するのはdynamic dispatch。

Qiita内だと、この記事とかSwiftのMethod dispatchについて詳しく書かれてます👏

GenericsとPATにおいて、前者で定義されたメソッドはstatic dispatchで実行されるが後者で定義されたメソッドはdynamic dispatchで実行される。
staticはコンパイル時にどのメソッドを走らせるか事前に決めるので実行速度が速い、ただしメモリーをより多く消費する。
逆にdynamicはプログラム実行中に動的に決定するので、その分実行速度は落ちるが効率的にメモリーを使用できる。

結論✍️

  • ケースバイケース
  • どちらでもよく、簡単なコードならとりあえず実行速度の速いGenericsを検討する
  • ただし、PATの方が表現力や可読性が高い(そもそもSwiftはProtocol oriented)
  • 自分はPATでやりたい

最後に

自分でもまだしっくり来てないです。誰かアドバイスください!!(説教でも可😜)

参考資料

SwiftにおけるMethod Dispatchについて - Qiita
Method Dispatch in Swift – RPLabs – Rightpoint Labs

8
4
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
4