Подтвердить что ты не робот

Вызов протокола по умолчанию по умолчанию из обычного метода

Мне интересно, можно ли достичь такой цели.
У меня есть такая игровая площадка:

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.

4b9b3361

Ответ 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