Расширение структур с помощью протоколов в Swift

#ios #swift #xcode

Вопрос:

У меня есть следующий фрагмент кода. Протоколы и расширения, которые я добавил, похоже, делают не совсем то, что я ожидаю. Что я упускаю?

 struct foo {  var getFoo: String  var getBar: bar    struct bar {  var getBar: String  } }  protocol FooProtocol {  var getFoo: String { get }  var getBar: BarProtocol { get } }  extension foo: FooProtocol {} // Type 'foo' does not conform to protocol 'FooProtocol'  protocol BarProtocol {  var getBar: String { get } }  extension foo.bar: BarProtocol {}  

Проблема в этом коде заключается в строке extension foo: FooProtocol {} , где мы пытаемся сказать, что, по сути foo.getBar.getBar , должно быть допустимым свойством. Однако Xcode выдает ошибку компиляции, в которой говорится, что «Тип» foo » не соответствует протоколу «FooProtocol».

Я могу исправить это, изменив следующее:

 protocol FooProtocol {  var getFoo: String { get }  var getBar: foo.bar { get } // instead of var getBar: BarProtocol { get } }  

Однако, похоже, строка extension foo.bar: BarProtocol {} должна означать FooProtocol , что нам все равно, дадим мы ее foo.bar или BarProtocol нет . Что я здесь упускаю?

Ответ @Drobs был правильным. Вот бонусный вопрос.

бонус

Теперь предположим, что мне нужно реализовать другую структуру, которая соответствует FooProtocol . Ни один из этих подходов не работает. В чем проблема?

 struct FooImplementation: FooProtocol { // Type 'FooImplementation' does not conform to protocol 'FooProtocol'  var getFoo: String  var getBar: BarProtocol }  

Нужно ли мне использовать что-то typealias для достижения этой цели?

Комментарии:

1. Я думаю, вы говорите о чем-то, связанном с типом, связанным с протоколом. 🙂

Ответ №1:

Вы хотите использовать associatedtype в протоколе. В этом случае, по сути, говорится, дайте мне тип, который реализует протокол BarProtocol .

 protocol FooProtocol {  associatedtype BarType: BarProtocol   var getFoo: String { get }  var getBar: BarType { get } }  protocol BarProtocol {  var getBar: String { get } }  struct Foo: FooProtocol {  var getFoo: String  var getBar: Bar   struct Bar: BarProtocol {  var getBar: String  } }  

Комментарии:

1. Потрясающе, это сработало! Я добавил дополнительный вопрос к своему первоначальному вопросу. Если я хочу реализовать struct FooImplementation: FooProtocol , как я могу достичь этого в общем виде?

2. Ты имеешь в виду вот так? struct FooImplementationlt;T: BarProtocolgt;: FooProtocol { var getFoo: String var getBar: T } FooImplementationlt;Foo.Bargt;(getFoo: "Foo", getBar: Foo.Bar(getBar: "Bar"))