【问题标题】:Generic function parameter default value泛型函数参数默认值
【发布时间】:2019-05-22 12:16:04
【问题描述】:

我正在使用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 的默认参数值吗?

【问题讨论】:

标签: swift generics


【解决方案1】:

这里的主要问题是.image 并不存在于每个&lt;Value, Format&gt; 对中。它只存在于&lt;UIViewController, UIImage&gt;&lt;UIView, UIImage&gt;。要在此处分配默认值,它必须适用于可以调用 verify 的所有方式。

默认参数总是可以用更少的参数表示为一个单独的函数,所以你只需要添加所需的重载而不是默认值。

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

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

【讨论】:

  • 我有几个选择:放弃默认参数,按照您的建议重构并创建一个新的enum 作为参数。但我仍在考虑任何“通用”解决方案。
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 2020-06-24
    • 1970-01-01
    • 2017-06-20
    • 2018-02-18
    • 2021-09-11
    • 1970-01-01
    • 2011-06-15
    • 2022-07-24
    • 2016-11-14
    相关资源
    最近更新 更多