Skip to content

Instantly share code, notes, and snippets.

@takasek
Created June 25, 2017 14:41
Show Gist options
  • Save takasek/f4d0562e883b8b31673ec39f887ec8c8 to your computer and use it in GitHub Desktop.
Save takasek/f4d0562e883b8b31673ec39f887ec8c8 to your computer and use it in GitHub Desktop.
「ジェネリクスは抽象型メンバーでエンコード可能。逆は可能かどうか」って話があったけど、Swiftでその「逆」を表現してみた。意図は合ってるかな…? #CodePiece #ジェネリクス勉強会
//付属型メンバーを持つ抽象型 Abstract1 を定義
protocol Abstract1 {
associatedtype A
associatedtype B
func tellMyType(a: A) -> Self.Type
}
//付属型メンバーを持つ抽象型 Abstract2 を定義
protocol Abstract2 {
associatedtype E
var element: E { get }
}
// Abstract1の抽象型メンバーを、ジェネリクスの型パラメータとして表現
struct Generic1<T: Abstract2, U>: Abstract1 where T.E == U {
typealias A = T
typealias B = U
func tellMyType(a: T) -> (Generic1<T, U>.Type) {
return type(of: self)
}
}
// Abstract2の抽象型メンバーを、ジェネリクスの型パラメータとして表現
struct Generic2<E>: Abstract2 {
let element: E
}
// 機能することを確認
Generic1().tellMyType(a: Generic2(element: "Element"))
// Generic1<__lldb_expr_2.Generic2<String>, String>.Type
extension Int: Abstract2 {
// このメソッド実装により、Int.E は Double だと推論される
var element: Double { return 1.0 }
}
Generic1().tellMyType(a: 10)
// Generic1<Int, Double>.Type
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment