概要
業務でInt型やDouble型を単純に2倍する関数を作りたい時に戸惑いましたのでググってみました。
/// これを型ごとに作ると、関数が増えてしまって冗長なので書きたくない
func multipleValue(_ value: Int) -> Int {
return value * 2
}
func multipleValue(_ value: Double) -> Double {
return value * 2
}
func multipleValue(_ value: CGFloat) -> CGFloat {
return value * 2
}
multipleValue(2) // 4
multipleValue(3.14) // 6.28
}
これをクールに一つの関数にまとめたいと思いました。
さてどうすればいいのかを考えるのが今回のテーマです。
ジェネリクスを使う
すぐに思いつくやり方は、ジェネリスクでパラメータを一つにまとめる方法です。
ジェネリスクはSwift のドキュメントでこう記されています。
ジェネリクスの用法としては
[Swift]ジェネリクスについて
が参考になります。
それはいいとして、ジェネリクスを使ってこんな風に書きたいです。
/// Tがジェネリックパラメータ
func multipleValue<T>(_ value: T) -> T {
return value * 2
}
multipleValue(2) // 4
multipleValue(3.14) // 6.28
}
これでいけるかと思ったのですがビルドエラーになってしまいました。
エラーの内容は
Binary operator '*' cannot be applied to operands of type 'T' and 'Int'
どうやらジェネリクスに二項演算子「*」などのoperatorが使えないみたいなエラーでした。
そのため、てっきりジェネリクスで数値を2倍にできないのかと諦めかけましたが、
エラーの文章からググってみましたら解決策が見つかりました。
Binary operator '+' cannot be applied to two 'T' operands
ということで Numeric protocol に準拠させたら使えるそうです。
/// Tがジェネリックパラメータ
func multipleValue<T: Numeric>(_ value: T) -> T {
return value * 2
}
multipleValue(2) // 4
multipleValue(3.14) // 6.28
}
これで目標のあらゆる数値を単純に2倍にする関数が作れました。
Numeric とは何なのか
乗算をサポートする値を持つ型だそうです。
Numericプロトコルを汎用制約として使用すれば、標準ライブラリ内の任意の数値型を操作する関数が作れるようになるとの事でした。
これで数値を操作する汎用メソッドが作れます。
と調べた後にこれについて詳しい資料がありましたので最後に貼って終わります。