開発メモ

開発関係のメモをいろいろと。たぶん。

SwiftのGenericsでハマったメモ その2

昨日の話の続きです。こっちは本当にハマった話。たぶん。

動作を確認した環境

環境 情報
Xcode 6.3 (6D570)
iOS 8.3
Swift 1.2
Date 2015/5/16

1つめのプロトコル

Genericsで線形補間は、一応、普通に動くようになりました。

/// 線形補間で必要になるプロトコル
protocol InterpolationArithmeticType: Equatable {
    func +(lhs: Self, rhs: Self) -> Self
    func -(lhs: Self, rhs: Self) -> Self
    func *(lhs: Self, rhs: Self) -> Self
    func /(lhs: Self, rhs: Self) -> Self
}

/// 使いたい型にプロトコルを適応させておく
extension Int: InterpolationArithmeticType {
}

extension Double: InterpolationArithmeticType {
}

extension CGFloat: InterpolationArithmeticType {
}

/// 単純な線形補間(Generics版 - OK)
func interpolation<T: InterpolationArithmeticType>(y0: T, y1: T, x0: T, x1: T, x: T) -> T {
    if x0 == x1 {
        return y0
    } else {
        return (y0 * (x1 - x) + y1 * (x - x0)) / (x1 - x0)
    }
}

2つめのプロトコル

せっかくなので、他の場所でもGenericsを使うようにしてみます。

/// 他の処理で必要になるプロトコル
protocol MakeObjectType: Equatable {

    /// 何からの処理
    func makeObject()
}

/// 使いたい型にプロトコルを適応させておく
extension Int: MakeObjectType {
    func makeObject() {
        // 省略
    }
}

extension Double: MakeObjectType {
    func makeObject() {
        // 省略
    }
}

extension CGFloat: MakeObjectType {
    func makeObject() {
        // 省略
    }
}

単純に、比較と特定の処理に対応したプロトコルです。ここまでしたところでコンパイルすると・・・

f:id:see_ku:20150516063736p:plain

こんなエラーが。

まったく別のプロトコルを定義してるのに、両方ともEquatableを継承しているので、結果的にシンボルが重複しているらしいです。

protocol MakeObjectType {

    /// 自力で『==』に対応
    func ==(lhs: Self, rhs: Self) -> Bool

    /// 何からの処理
    func makeObject()
}

その証拠に(?)、こんな風に書き換えればコンパイルが通るようになります。けど、そういうわけにも行かないケースも有るわけで・・・ これはもう単純に、Swiftコンパイラのバグのような気が。今のSwiftでGenericsに手を出すのは、茨の道かなぁ。