#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"))