LoginSignup
3
3

More than 3 years have passed since last update.

[Swift] IntやDoubleなどの数字オブジェクトを2倍にする関数でジェネリクスを使ってみた

Posted at

概要

業務で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ドキュメント

ジェネリクスの用法としては
[Swift]ジェネリクスについて

ジェネリック関数 | ジェネリクス | Swift

が参考になります。

それはいいとして、ジェネリクスを使ってこんな風に書きたいです。

    /// Tがジェネリックパラメータ
    func multipleValue<T>(_ value: T) -> T {
        return value * 2
    }

    multipleValue(2) // 4
    multipleValue(3.14) // 6.28
}

これでいけるかと思ったのですがビルドエラーになってしまいました。

image.png

エラーの内容は

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

乗算をサポートする値を持つ型だそうです。

Numericプロトコルを汎用制約として使用すれば、標準ライブラリ内の任意の数値型を操作する関数が作れるようになるとの事でした。

これで数値を操作する汎用メソッドが作れます。

と調べた後にこれについて詳しい資料がありましたので最後に貼って終わります。

Protocol-Oriented Integers に想うジェネリックプログラミングの未来

3
3
0

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
3
3