0

Swift でプロトコルと拡張機能を活用しようとしていますが、理解できないコンパイル エラーが発生します。

次のような Shape を定義する 2 つのプロトコルを宣言するとします。

protocol Shape {
  var sides : Int { get }
  var fill : Fill { get }
}

protocol Fill {
  var color : UIColor { get }
}  

これを実装するために、1 つは Square 用、もう 1 つはソリッド フィル用の 2 つの構造体を定義します。このような:

struct SolidFill : Fill {
  var color : UIColor
}

struct Square : Shape {
  var sides : Int = 4
  var fill : SolidFill = SolidFill(color: UIColor.blackColor())
}

「タイプ 'Square' はプロトコル 'Shape' に準拠していません」というコンパイル エラーが表示されます。var fill : Fillコンパイルエラーのように塗りつぶしのタイプを強制的に塗りつぶすと、消えます。プロトコルで許可されているものよりも具体的なタイプを Square で指定できないのはなぜですか?

この特定の例では、塗りつぶしに Enum を使用するか、何か他のものを作り直すことで、このパターンを使用しないように変更できることに気付きました。fill をプロトコルに準拠した型にすることができない理由を知りたいだけです。

4

2 に答える 2

1

意味がないからです。

プロトコルに準拠するコードを書き始める前に、プロトコルについて考え、通常の使用例 (およびプロトコルの設計方法) では、コードはプロトコルの知識だけで書かれ、ゼロであることに気付く必要があります。プロトコルを実装する特定のクラスまたは構造体の知識。

したがって、プロトコルが、おそらく やFillなど、それを継承する他のプロトコルを持つことは理にかなっています。SolidFillStripedFill

StripedFill先に進み、プロトコルを例に追加しましょう。Square次に、構造体を見て、プロトコルが実装されていない理由を見てみましょう。Shapeこれには、一部にFillプロパティが必要です。

struct Square : Shape {
  var sides : Int = 4
  var fill : SolidFill = SolidFill(color: UIColor.blackColor())
}

Squarefillプロパティに割り当てることができるのは、SolidFillプロトコルを実装するものだけです。しかし、プロトコルでは、シェイプがプロトコルに準拠する任意Shapeのプロパティに割り当てることができる必要があります。また、プロトコルから継承されたプロトコルが呼び出された場合、そのプロトコルを実装するオブジェクトも含まれます (プロトコルも実装するかどうかに関係なく)。fillFillStripedProtocolFillSolidFill

しかし、あなたのSquareクラスはこれを許可していません。あなたのSquareクラスは、Fillとその子孫の特定の子のみを許可しますが、その兄弟は許可しません...SolidFillの潜在的な兄弟の除外が、あなたがやろうとしていることを実行できない理由です。

ただし、できることは次のとおりです。

struct Square: Shape {
    var sides: Int = 4
    var fill: Fill = SolidFill(color: UIColor.blackColor())
}

したがって、この場合、間違いなく に を割り当てていSolidFillますSquareが、fillプロパティがプロトコルで定義されているものと一致することを許可し、SolidFillの兄弟がfillプロパティに割り当てられることを許可しています。

于 2015-11-10T13:35:53.240 に答える
0

ゲッターだけで理論的には問題ないかもしれませんが、セッターがあった場合、誰かがプロトコルを満たす別のオブジェクトを設定しようとする可能性があるため、プロトコルを完全に満たすことはできません。

それが十分に価値があると思われる場合は、変数のみを取得するように要求するレーダーを上げることができますが、おそらくそれを回避する方がよいでしょう。

あなたはこれを行うことができます:

struct Square : Shape {
  var sides : Int = 4
  var fill : Fill { solidFill }
  private var solidFill = SolidFill(color: UIColor.blackColor())
}
于 2015-11-10T13:35:08.020 に答える