Вызов протокола по умолчанию по умолчанию из обычного метода
Мне интересно, можно ли достичь такой цели.
У меня есть такая игровая площадка:
protocol Foo {
func testPrint()
}
extension Foo {
func testPrint() {
print("Protocol extension call")
}
}
struct Bar: Foo {
func testPrint() {
// Calling self or super go call default implementation
self.testPrint()
print("Call from struct")
}
}
let sth = Bar()
sth.testPrint()
Я могу предоставить реализацию по умолчанию в extension
, но что, если Bar
нужно все, что есть в реализации по умолчанию плюс дополнительные вещи?
Это как-то похоже на вызов методов super.
в class
es для выполнения требования реализации каждого свойства и т.д., Но я не вижу возможности достичь того же с помощью structs
.
Ответы
Ответ 1
Я не знаю, продолжаете ли вы искать ответ на этот вопрос, но способ сделать это - удалить функцию из определения протокола, отбросить ваш объект до Foo
и затем вызвать метод на нем:
protocol Foo {
// func testPrint() <- comment this out or remove it
}
extension Foo {
func testPrint() {
print("Protocol extension call")
}
}
struct Bar: Foo {
func testPrint() {
print("Call from struct")
(self as Foo).testPrint() // <- cast to Foo and you'll get the default
// function defined in the extension
}
}
Bar().testPrint()
// Output: "Call from struct"
// "Protocol extension call"
По какой-то причине он работает только в том случае, если функция не объявлена частью протокола, но определена в расширении протокола. Идите фигуру. Но он работает.
Ответ 2
Ну, вы можете создать вложенный тип, соответствующий протоколу, создать его экземпляр и вызвать метод на нем (неважно, что вы не можете получить доступ к данным типа, поскольку реализация внутри расширения протокола не может ссылаться на него в любом случае), Но это не решение, которое я бы назвал элегантным.
struct Bar: Foo {
func testPrint() {
// Calling default implementation
struct Dummy : Foo {}
let dummy = Dummy()
dummy.testPrint()
print("Call from struct")
}
}
Ответ 3
Спасибо за сообщение! Если вы поместите определение функции в протокол, тогда, когда объект передается в качестве протокола, он видит только объектную версию функции и, поскольку вы вызываете ее внутри себя, вы получаете новый адрес Apple...
Я попробовал такую версию:
import UIKit
protocol MyProc
{
}
protocol MyFuncProc
{
func myFunc()
}
extension MyProc
{
func myFunc()
{
print("Extension Version")
}
}
struct MyStruct: MyProc, MyFuncProc
{
func myFunc()
{
print("Structure Version")
(self as MyProc).myFunc()
}
}
(MyStruct() as MyFuncProc).myFunc()
Это дает вывод:
Structure Version
Extension Version