![](https://tgfile.tg-static.com/static/web/img/placeholder.gif)
『プロトコル拡張を、それに準拠する将来の型で制約して、既定の実装を添えよう』という話を発端にした考察
-
es_kumagai
- 1924
- 7
- 2
- 0
![](https://tgfile.tg-static.com/static/web/img/placeholder.gif)
あれ?extension MyProtocol where Self : ClassA みたいに制限つけた場合もデフォルト実装と言うのだろうか(´・ω・`)?
2016-03-07 23:57:24![](https://tgfile.tg-static.com/static/web/img/placeholder.gif)
@eduraaa制限のあるデフォルト実装じゃないですかね。個人的にはデフォルト実装はそんな感じで使ったほうが良いと思っているんですけどどうですかね?
2016-03-08 00:00:25![](https://tgfile.tg-static.com/static/web/img/placeholder.gif)
@eduraaa 不可解ですけどもしかして、クイックヘルプで型が "Self.Type" になっているのも関係してる…? pic.twitter.com/G9ktxMUnST
2016-03-08 00:05:13![](https://pbs.twimg.com/media/Cc9D1C7UIAAe2XY.jpg:medium)
![](https://tgfile.tg-static.com/static/web/img/placeholder.gif)
@eduraaa ちなみに type = self.dynamicType as! ClassB.Type だと型が "ClassB.Type" になって type.extensionOnly も "override" でした。 pic.twitter.com/r78mPPSsJq
2016-03-08 00:08:17![](https://pbs.twimg.com/media/Cc9Eh4bUAAE-2Bs.jpg:medium)
![](https://tgfile.tg-static.com/static/web/img/placeholder.gif)
憶測。self.dynamicType は Self.Type 型になって、動的ディスパッチ。ただ、静的メソッドは型に関連づいているので、そのまま Self のが呼ばれる? #swift
2016-03-08 00:11:29![](https://tgfile.tg-static.com/static/web/img/placeholder.gif)
self.dynamicType を print するときは Type の実装までは見てないですけど、普段なら CustomStringConvertible の description が呼ばれるので、こちらは動的ディスパッチな予感。そこにギャップは生まれそう。 #swift
2016-03-08 00:13:05![](https://tgfile.tg-static.com/static/web/img/placeholder.gif)
ああ、ちょっと勘違い。ちなみに「既定の実装を上書き」という言葉が一般的ですけど、厳密にはプロトコルの実装が消されることはなくて「隠蔽」な感じみたい。 gist.github.com/ca9958eb735dbb… #swift pic.twitter.com/pt1aELQwgy
2016-03-08 00:27:41![](https://pbs.twimg.com/media/Cc9I-I4UUAAK0TD.jpg:medium)
![](https://tgfile.tg-static.com/static/web/img/placeholder.gif)
わかった。たぶん、クラス A 内における、クラス B のインスタンスに対する dynamicType の動きはこれ。確かに未来の型なんて今、分かるはずがない。 gist.github.com/735ad94903cb9a… #swift pic.twitter.com/BAoC5IVeC5
2016-03-08 00:36:48![](https://pbs.twimg.com/media/Cc9LDvdUUAEl-vO.jpg:medium)
![](https://tgfile.tg-static.com/static/web/img/placeholder.gif)
そして、型に実装を求めないメソッドを A.Type に対して呼ぼうとするので、たぶん A の方のメソッドが呼ばれる、感じかしら。 #swift
2016-03-08 00:39:28![](https://tgfile.tg-static.com/static/web/img/placeholder.gif)
あれ、やっぱり微妙に検証が足りない気がしてきた。プロトコルでも自分が描いた dynamicType の動きが成り立つのか、付属型付きのプロトコルでも成立するのか。明日また考えてみよう。
2016-03-08 00:57:29![](https://tgfile.tg-static.com/static/web/img/placeholder.gif)
これはこのQiitaの記事とも通じるな( `・ω´・) Swiftのプロトコルエクステンションの罠 - Qiita qiita.com/omochimetaru/i… (Reading togetter.com/li/947075 ) twitter.com/es_kumagai/sta…
2016-03-08 02:11:59![](https://tgfile.tg-static.com/static/web/img/placeholder.gif)
そして、また混乱してきた。プロトコルに宣言を入れた場合とそうでない場合の、プロトコル拡張での定義にそれぞれ別の名前が欲しいかもしれない。ここに同じ言葉を当てて考えているとうっかり混乱してしまう気がする。 #swift
2016-03-06 14:26:02![](https://tgfile.tg-static.com/static/web/img/placeholder.gif)
とりあえず復習的な、普通のインスタンスメソッドに対するプロトコル拡張の動きのところ。 gist.github.com/540e3864805c18… #swift pic.twitter.com/9O7xxgX57m
2016-03-08 11:19:57![](https://pbs.twimg.com/media/Cc_eQ0AUAAEGCQA.jpg:medium)
![](https://tgfile.tg-static.com/static/web/img/placeholder.gif)
次に静的メソッド周りを調べてみよう…と思った途中、面白い根拠的なものを発見した。プロトコルで宣言したのとしないのとで、メソッド実行時の根本の型が違うみたい。 gist.github.com/5cda0b49367804… #swift pic.twitter.com/tngBDj0Y0F
2016-03-08 11:32:18![](https://pbs.twimg.com/media/Cc_hFmnVIAEtLTA.jpg:medium)
![](https://tgfile.tg-static.com/static/web/img/placeholder.gif)
そしてすごくどうでもいいけれど、もしかしてプレースホルダーリテラル(?)を発見した…と思ったけど、これは Xcode のコードスニペットで使えるのと同じか。 gist.github.com/bb2a8d6e18a2ff… #swift pic.twitter.com/GvUf3NhW0Y
2016-03-08 11:36:43![](https://pbs.twimg.com/media/Cc_iGSMUEAAFnlI.jpg:medium)
![](https://tgfile.tg-static.com/static/web/img/placeholder.gif)
とりあえず、プロトコルに宣言した時としない時とでメソッド呼び出しの根本に当たる部分が `Self` か `A` かに変化するって、プロトコル拡張を感覚的に捉える上でかなり重要になりそうなところな気がする。 #swift
2016-03-08 11:38:43![](https://tgfile.tg-static.com/static/web/img/placeholder.gif)
ちなみに先ほどの「型からインスタンス変数を呼び出す」書き方は普段、こんな感じに使えたりします。 gist.github.com/bb0d9ecf078158… #swift pic.twitter.com/PMRVWxgPhb
2016-03-08 11:56:06![](https://pbs.twimg.com/media/Cc_miRBUAAAiy4c.jpg:medium)
![](https://tgfile.tg-static.com/static/web/img/placeholder.gif)
あれ… プロトコルに付属型を付けてみたら classA1.extensionVar の結果が 'not override" になった( ´ △ ` ) gist.github.com/b65f0e6a655af4… #swift pic.twitter.com/Oll7qkl5gR
2016-03-08 12:04:24![](https://pbs.twimg.com/media/Cc_ob3IVAAEgL4O.jpg:medium)
![](https://tgfile.tg-static.com/static/web/img/placeholder.gif)
静的メソッドに限らず、インスタンスメソッドでも、付属型をつけると同じように振る舞うみたい。 gist.github.com/b7869e4b7b7b6e… #swift pic.twitter.com/fpbb0bUAl1
2016-03-08 12:13:26![](https://pbs.twimg.com/media/Cc_qgRpUkAArU8O.jpg:medium)
![](https://tgfile.tg-static.com/static/web/img/placeholder.gif)
でもそうなんですよね。昨日の話で、もし dynamicType が Self.Type 型で扱われるとしたら、付属型の型は使えないはずなので辻褄が合わない。 gist.github.com/8b1aa8af77c0da… #swift pic.twitter.com/JtXzKKwibM
2016-03-08 12:24:12![](https://pbs.twimg.com/media/Cc_s9-gUMAMbeC1.jpg:medium)
![](https://tgfile.tg-static.com/static/web/img/placeholder.gif)
あら、すごい。プロトコル拡張の中では普通に "Self.Type" が使えるのね。付属型に型が割り当てられているものとみなせば使えても自然か。 gist.github.com/31b2fc36b000d0… #swift pic.twitter.com/co8lkciEhi
2016-03-08 12:28:54![](https://pbs.twimg.com/media/Cc_uCzIUEAEjgxB.jpg:medium)
![](https://tgfile.tg-static.com/static/web/img/placeholder.gif)
自分も「Self ってなんだろう…?」みたいになってきた。とりあえず Self.self で Self.Type が取れるみたいなので、一応「まさに自分自身」みたいにも見える。 #swift pic.twitter.com/94PfuBoYQT
2016-03-08 12:45:05![](https://pbs.twimg.com/media/Cc_xv3uUIAAMi2z.jpg:medium)
![](https://tgfile.tg-static.com/static/web/img/placeholder.gif)
ああ、わかった。Self って、インスタンスメソッドでも静的メソッドでも常に「自分自身の型のメタタイプ」の事で。self はインスタンスメソッドの時は「インスタンスの実際の型」で、静的メソッドの時は「Self と同等」ですね。 #swift
2016-03-08 14:11:42