疑問
Protocol 'ExtensionCompatible' requirement 'ex' cannot be satisfied by a non-final class ('UIImage') because it uses 'Self' in a non-parameter, non-result type position
(具体的な変数名やプロトコル名は場合によって変わりますが、)このエラーが意味することの自分の認識が正しいかどうかお聞きしたいです。
自分の思考は下記です。
詳細
extension の定義を独自に設定したものというのを明確にするために、exというのをつけることがあると思います。
その際に下記のような実装でそれが実現できます。
swift
1 2/// exの型となるクラス 3public final class Extension<Base> { 4 let base: Base 5 public init(_ base: Base) { 6 self.base = base 7 } 8} 9 10/// exの定義 11public protocol ExtensionCompatible { 12 //(疑問の箇所) これ消して、 exの型 Extension<Self> でいいのでは? 13 associatedtype CompatibleType 14 15 var ex: CompatibleType { get } 16} 17 18// exの戻り値を定義 19public extension ExtensionCompatible { 20 var ex: Extension<Self> { 21 return Extension(self) 22 } 23} 24 25/// 拡張していることの宣言 26extension UIImage: ExtensionCompatible { } 27 28
この時、結局exの型はExtension<Self>なので、コメントの「(疑問の箇所)」に記載の通り連想型の定義を無くし、exの型をExtension<Self>に設定すればいいのではと思いました。
ただ、そうした場合、以下のようなエラーとなります。
Protocol 'ExtensionCompatible' requirement 'ex' cannot be satisfied by a non-final class ('UIImage') because it uses 'Self' in a non-parameter, non-result type position
これについては、
ExtensionCompatibleプロトコルにて、final classではないUIImageが、引数や戻り値ではないところでSelfを用いて参照されているのでエラーとなっている、という理解をしています。
故に、連想型を介した場合は単純にSelfがプロトコル内で参照されなくなり、問題なくなるという認識です。
そして、そのような対応すること(つまり、final classとするか or 連想型とするかの対応をすること)が要求される理由としては、もしそうのような対応をしなかった場合にSelfに入るインスタンスの型が一意に確定しないためである、という認識です。(Selfをいれているにも関わらず複数の型が入ることが想定されることが問題?)
このような理解をしているのですが認識はあっていますでしょうか?
(「ExtensionCompatibleプロトコルにて、」 〜 「想定されることが問題)」 まで )
助言頂けますと幸いです。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/06/17 13:33