Можем ли мы иметь значения по умолчанию для аргументов метода в расширениях протокола? Если да, то можем ли мы переопределить эти методы в структурах, реализующих этот протокол?

Можем ли мы иметь значения по умолчанию для аргументов метода в расширениях протокола?

Если да, то можем ли мы переопределить эти методы в структурах, реализующих этот протокол?

Я делаю это, но у меня неожиданные результаты. Это почему? Спасибо!

import Foundation

protocol Datasource {
    func getLetter(_ uppercased: Bool) -> String
}

extension Datasource {

    func getLetter(_ uppercased: Bool = true) -> String {
        return uppercased ? "B" : "b"
    }
}

struct ADatasource: Datasource {

    func getLetter(_ uppercased: Bool = true) -> String {
        return uppercased ? "A" : "a"
    }
}

let datasource: Datasource = ADatasource()
datasource.getLetter(true) // returns "A"
datasource.getLetter()     // returns "B"   

person offcourse    schedule 29.01.2019    source источник
comment


Ответы (2)


Честно говоря, не уверен, почему .getLetter() выбирает расширение протокола, а не перезаписанную реализацию.

Тем не менее, я знаю хороший обходной путь, который позволит добиться того, что вы пытаетесь сделать:

protocol Datasource {
    func getLetter(_ uppercased: Bool) -> String
}

extension Datasource {

    func getLetter() -> String {
        return getLetter(true)
    }

    func getLetter(_ uppercased: Bool) -> String {
        return uppercased ? "B" : "b"
    }
}

struct ADatasource: Datasource {

    func getLetter(_ uppercased: Bool) -> String {
        return uppercased ? "A" : "a"
    }
}

let datasource: Datasource = ADatasource()
datasource.getLetter(true) // returns "A"
datasource.getLetter()     // now returns "A"
person XmasRights    schedule 29.01.2019

Если я правильно помню, это из-за динамической отправки и статической отправки. Методы, объявленные в расширениях протокола, не отправляются динамически.

Поскольку метод без явного аргумента в протоколе не определен, вызов отправляется статически. И поскольку вы определили datasource как тип Datasource, вместо реализации ADatasource вызывается реализация протокола.

Если вы удалите явный тип и просто используете let datasource = ADatasource(), он будет работать, как и ожидалось.

person Rengers    schedule 29.01.2019