Swiftの関数に対する実装と抽象の分離の実現(関数のDI)

31646 ワード

話すこと

こんちには, です。Twitterで流れてくるポケモンのマンガがどれも良すぎて毎日つらいです,早くポケモンと暮らしたい。

今回は関数に対する実装と抽象の分離について考察します。

実装と抽象の分離を考えます,以下のような対応を考えると関数も抽象を捉えられそうです。

実装 抽象
構造体・クラス プロトコル
関数 ?

純粋関数の場合は明確に実装と抽象が分離できます。下記の通常の関数の定義では実装はビルド時に決定されますが,分離した場合には実行時まで実装の選択が遅延されます。そのため依存性の注入が実行時に可能です。

// 通常の関数の定義
func add(first: Int, second: Int) -> Int {
  first + second
}

// 分離した場合の定義
let impl: (Int, Int) -> Int = { first, second in first + second }
func add(first: Int, second: Int) -> Int {
  impl(first, second)
}

高階関数

さて,このままでは少し使いにくいです。そのため関数を呼ぶと実装が返されると筋が良さそうです,これを高階関数と呼びます。またこれを実現するためには関数型にラベルがあると嬉しいですね。
下記に実装例を示します。しかしながらラベルを付与することは現在できません。Swift3よりクロージャでは型の順序のみで判別されることになるため分離した場合の定義を関数では表現できそうにないです。