我们可以定义一个函数来拆除厄运的可选金字塔,而不是使用多个可选绑定(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/