ͦͷ༰ P ͷఆٛͱ΄΅ಉ͡ܗʹͳΔɻ • ݺͼग़͢ଆ͕ <T> ͷਅͷܕ S ͷ P ͷPWTΛηοτͰ͢ɻ 12 https://github.com/apple/swift/blob/main/docs/ABI/TypeLayout.rst#existential-container-layout 21
{ var u: T = t // NG // u = S() return u } <T> ͦͷίϯςΩετʹ͓͚Δɺ͋ΔಛఆͷܕͰ͋Γɺ ͨͱ࣮͑ߦ࣌ʹͦ͏ͩͬͨͱͯ͠ɺܕνΣοΫʹ͓͍ͯ S Ͱ K Ͱͳ͍ɻ ҾͰͨ͠ t: T ͱɺͦͷίϐʔͷ u: T ฦΓͷ T ಉ͡ܕͰ͋Γɺ࣮ߦ࣌ʹ͓͍ͯͨ͠ܕ͕ฦͬͯ͘ Δɻ 63
{ S() } func makeP2() -> some P { S() } func main() { let p = makeP() let p2 = makeP2() let a = p2.a() // error: cannot convert value of type // '(some b.P).A' (associated type of protocol 'P') // to expected argument type // '(some b.P).A' (associated type of protocol 'P') p.useA(a: a) } 75
A func useA(_ a: A) } func useP(_ p: any P) { // ok p.a() // error: member 'useA' cannot be used on value of type 'any P'; // consider using a generic constraint instead p.useA(1) } 95
useP(_ p: Self) } func useP(_ p: any P) { // ok p.p() // error: member 'useP' cannot be used on value of type 'any P'; // consider using a generic constraint instead p.useP(p) } 96
associatedtype B: BP func p() -> Self func a() -> A func b() -> B } func useP(_ p: any P) { let p2: any P = p.p() let a: Any = p.a() let b: any BP = p.b() } ͜ͷ upper boundͳexistentialܕͷੜશ͘৽͍͠ϩδοΫ 97
} callerଆͰऔಘ͕ͨؔ͠ड͚औΔ some P Λ࡞Δํ๏͕ແ͍ɻ 14 14 https://github.com/apple/swift-evolution/blob/main/proposals/0341-opaque-parameters.md#opaque- parameters-in-consuming-positions-of-function-types 123
var b: B var c: C public func getA() -> A { a } public func getB() -> B { b } public func getC() -> C { c } } public func ortGeneric1() -> C<Int, Int, some P> { C<Int, Int, S>(a: 0, b: 1, c: S()) } public func ortGeneric2() -> C<some P, (some P, some P), some P> { C<S, (S, S), S>(a: S(), b: (S(), S()), c: S()) } func main1() { ortGeneric1().getC() } func main2() { ortGeneric2().getC() } 141
associatedtype B: P where B.A == Int } func getBFromQ<T: Q>(_ q: T) -> T.B { ... } func eraseQAssoc(q: any Q) { let b = getBFromQ(q) } getBFromQͷฦΓͷܕ <U: P> where P.A == Int ͕ͩɺ b ʹerase͢Δͱ͖ʹ any P ʹͳΓɺA == Int ͷ੍͕ࣦ͢Δɻ 175
associatedtype B: P where B.A == Int } func getP<T: P>(_ p: T) func getBFromQ<T: Q>(_ q: T) -> T.B { ... } func eraseQAssoc(q: any Q) { // A == Int ͕ࣦ͢ΔͷͰ as any P ͕ඞཁ getP(getBFromQ(q)) // ੍ࣦ͕ڐ༰͞Ε͕ͨɺopen੍͢ΔͨΊgetP͕ݺͼग़ͤͳ͍ getP(getBFromQ(q) as any P) // ੍ࣦΛڐ༰͠ɺopenͷ੍ΛແޮԽͨ͠ͷͰɺgetP͕ݺͼग़ͤΔ getP((getBFromQ(q) as any P)) } 188