swift - 如何使用通用函数拆除 swift 的可选末日金字塔

标签 swift generics option-type

我们可以定义一个函数来拆除厄运的可选金字塔,而不是使用多个可选绑定(bind)。

func if_let<T, U, V> (a: T?, _ b: U?, _ c: V?, fn:(T, U, V) -> () ){
    if let a = a {
        if let b = b {
            if let c = c {
                fn(a, b, c)
            }
        }
    }
}

那么我可以这样写:

var s1: String? = "s11"
var s2: String? = "s22"
var s3: String? = "s33"

if_let(s1, s2, s3) { s1, s2, s3 in
    print(("\(s1) - \(s2) - \(s3)"))
}

但是,问题是如何使这个 if_let 函数更通用,以便它可以接受任意数量的参数。我的实现是这样的:

func if_let<T> (values: T?..., fn:(params: [T]) -> ()) {
    for value in values {
        guard value != nil else { return }
    }
    let unwrappedArray = values.map{ $0! }
    fn(params: unwrappedArray)
}

我尝试映射数组并获取一个所有元素都已展开的新数组,然后调用 fn。但是当我再次运行测试时,出现编译错误:

Cannot convert value of type String? to expected argument type '_?'

谁能解释并修复这个错误?

最佳答案

问题是您的 if_let 的第二个实现不再将 (T,U,V)->() 类型的函数作为最终参数。它现在需要 ([T])->() 类型的函数。如果你用一个调用它,它会编译:

if_let(s1, s2, s3) { args in // or: (args: [String])->() in
    print("\(args[0]) - \(args[1]) - \(args[2])")
}

关于swift - 如何使用通用函数拆除 swift 的可选末日金字塔,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34428008/

相关文章:

swift - 如何使用swift将方向度数转换为文字?

swift - 直接从 UITabBarController 和通过 UINavigationController 选择 UIViewController

json - 有关用于 Swift 3 的 Instagram API 更改的问题。纬度和经度,按#hastag 搜索

Java8 函数式接口(interface)

java - ArrayList 包含错误的类型对象,没有明确的原始类型转换

c# - 依赖注入(inject)机制以提供通用服务接口(interface)的最具体实现

haskell - 从可选解析器列表中取出单个后续值

ios - 使用委托(delegate)和协议(protocol)的 Collection View Cell Action

c++ - std::optional 枚举的比较运算符

ios - Swift 中 Optional 的技术定义是什么?