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() { // 省略 } }
単純に、比較と特定の処理に対応したプロトコルです。ここまでしたところでコンパイルすると・・・
こんなエラーが。
まったく別のプロトコルを定義してるのに、両方ともEquatableを継承しているので、結果的にシンボルが重複しているらしいです。
protocol MakeObjectType { /// 自力で『==』に対応 func ==(lhs: Self, rhs: Self) -> Bool /// 何からの処理 func makeObject() }
その証拠に(?)、こんな風に書き換えればコンパイルが通るようになります。けど、そういうわけにも行かないケースも有るわけで・・・ これはもう単純に、Swiftコンパイラのバグのような気が。今のSwiftでGenericsに手を出すのは、茨の道かなぁ。