通用函数参数默认值

时间:2019-05-22 12:16:05

标签: swift generics swift-snapshot-testing

我正在使用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 个答案:

答案 0 :(得分:1)

这里的主要问题是并非每个.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)
}

答案 1 :(得分:0)

参考@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)