Created
February 15, 2016 09:10
-
-
Save niwatako/d8e6c53ab4ff96e55936 to your computer and use it in GitHub Desktop.
これはバグじゃないの!? swift の protocol extension による デフォルト実装と文脈による優先順位について #CodePiece
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// A とそのサブクラス B が、"プロパティnameを持つ" SomeProtocolに準拠することを宣言。 | |
class A {} | |
class B: A {} | |
protocol SomeProtocol { var whatYourName: Void { get } } | |
extension A: SomeProtocol {} | |
// Aにnameのデフォルト実装を用意 | |
extension SomeProtocol where Self: A { | |
var whatYourName: Void { print("My name is A") } | |
} | |
// BはAを継承していますが、更にデフォルト実装を上書きします | |
extension SomeProtocol where Self: B { | |
var whatYourName: Void { print("My name is B") } | |
} | |
// この状態では、それぞれ異なる name の実装が機能します | |
A().whatYourName // My name is A | |
B().whatYourName // My name is B | |
// ところが、インスタンスのプロパティとして格納された途端に... | |
class C { | |
var person: SomeProtocol | |
init(_ person: SomeProtocol) { self.person = person } | |
} | |
let cA = C(A()) | |
let cB = C(B()) | |
// Bの name 実装が スーパークラス A の実装になってしまいました! | |
cA.person.whatYourName // My name is A | |
cB.person.whatYourName // My name is A |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment