Стандартное значение параметра функции по умолчанию - PullRequest
2 голосов
/ 22 мая 2019

Я работаю с swift-snapshot-testing и обнаружил проблему со значением параметра универсальной функции по умолчанию.

Фреймворк предоставляет такой метод:

func verifySnapshot<Value, Format>(matching value: Value,
                                   as snapshotting: Snapshotting<Value, Format>,
                                   snapshotDirectory: String? = nil) -> String? 

где Snapshotting - это общая структура, подобная этой:

struct Snapshotting<Value, Format> {}

extension Snapshotting where Value == UIViewController, Format == UIImage {
    static var image: Snapshotting<UIViewController, UIImage> {
      :
    }
}

extension Snapshotting where Value == UIView, Format == UIImage {
    static var image: Snapshotting<UIView, UIImage> {
      :
    }
}

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

func verify<Value, Format>(matching value: Value,
                           as snapshotting: Snapshotting<Value, Format>) {
    let snapshotDirectory = "/path"

    let failure = verifySnapshot(matching: value,
                                 as: snapshotting,
                                 snapshotDirectory: snapshotDirectory)

    print(failure ?? "Done!")
}

Но когда я хочу дать snapshotting значение параметра по умолчанию .image, оно не компилируется для ошибки Ambiguous reference to member 'image'

func verify<Value, Format>(matching value: Value,
                           as snapshotting: Snapshotting<Value, Format> = Snapshotting<Value, Format>.image)

Мой вопрос: может ли Swift определить универсальный тип Format для значения параметра по умолчанию?

Ответы [ 2 ]

1 голос
/ 22 мая 2019

Основная проблема здесь в том, что .image существует не для каждой пары <Value, Format>. Он существует только для <UIViewController, UIImage> и <UIView, UIImage>. Чтобы назначить здесь значение по умолчанию, оно должно быть применимо ко всем способам, которыми может вызываться verify.

Параметры по умолчанию всегда могут быть выражены в виде отдельной функции с меньшим количеством параметров, поэтому вам просто нужно добавить требуемые перегрузки, а не значение по умолчанию.

func verify(matching value: UIViewController) {
    verify(matching: value, as: .image)
}

func verify(matching value: UIView) {
    verify(matching: value, as: .image)
}
0 голосов
/ 22 мая 2019

Ссылка на ответ @Rob Napler Я сделал обходной путь, чтобы интерфейс выглядел со значением по умолчанию:

///interface to accept snapshotting argument 
func verify<Value, Format>(matching value: Value,
                           as snapshotting: Snapshotting<Value, Format>)

///interfaces to accept specific kind of value 
func verify(matching value: UIView)
func verify(matching value: UIViewController)
:
:

, и мы можем назвать его как

verify(matching: aView)

или

verify(matching: aView, as: .image)
...