我正在阅读Functional Swift book并演示Optionals,第8章提到了如何定义??
运算符来处理结果类型,这是以前定义的类型。但是,当我尝试使用此运算符时,我看不到调用的重载版本。我是否正确使用此操作符?
// Define ErrorType
enum LookupError: ErrorType {
case CapitalNotFound
case PopulationNotFound
}
enum Result<T> {
case Success(T)
case Error(ErrorType)
}
// Overloaded operator
func ??<T>(result: Result<T>, handleError: ErrorType -> T) -> T {
print("overloaded result: \(result)")
switch result {
case let .Success(value): return value
case let .Error(error): return handleError(error)
}
}
我正在使用这样的运营商:
let r:Result<String>? = Result<String>.Success("A-Ok")
let d = Result<String>.Success("Error")
let result = r ?? d
这样做表明:
Result: Success("A-Ok")
但是在任何时候都不会调用重载的运算符。
答案 0 :(得分:2)
你的表达式let result = r ?? d
与你的重载的函数签名不匹配,因此它不知道你想要调用它的函数(而是调用常规的nil合并运算符)。 / p>
让我们来看看签名:
func ??<T>(result: Result<T>, handleError: ErrorType -> T) -> T { ...
您几乎可以正确使用调用中的第一个参数,它应该是Result<T>
类型,但不是可选的。但是,自定义??
函数中的第二个参数是闭包,一个函数类型ErrorType
并返回泛型T
(在我们的示例中:{{ 1}}),你的调用中的第二个参数必须是这样的闭包类型。因此,您的两个String
实例Result<String>
和r
不应与您的自定义d
运算符一起使用,而应与相应的闭包一起使用。
定义??
的两个示例实例 - 一个包含错误,一个包含成功---
Result<String>
现在,为了在我们对它的调用中符合你的var r:Result<String> = Result<String>.Success("A-Ok")
var d:Result<String> = Result<String>.Error(LookupError.CapitalNotFound)
函数签名,我们将表达式的右侧构造成一个闭包,如下所示:
??
好的,现在我们实际上称你的var result = r ?? {
err in
switch err as! LookupError {
case .CapitalNotFound: return "Couldn't find capital"
case .PopulationNotFound: return "Couldn't find population"
}
}
print(result) /* A-Ok */
result = d ?? {
err in
switch err as! LookupError {
case .CapitalNotFound: return "Couldn't find capital"
case .PopulationNotFound: return "Couldn't find population"
}
}
print(result) /* Couldn't find capital */
超载了。但是,上面的这些表达式看起来非常混乱,特别是如果我们想要经常调用我们的自定义??
运算符。
不是每次执行错误检查时都发布相同的闭包,我们可以创建一个我们使用的闭包的句柄。使用句柄---就像上面的闭包一样---作为调用自定义??
运算符的右侧参数:
??
这可能甚至可以做得更整洁,但你得到它的要点:我们必须确保我们的调用及其参数符合我们的自定义函数的签名。
答案 1 :(得分:0)
r
Result
包含在Optional
中,因此您可以获得适用于期权的??
运营商的版本。
由于您未在示例中使用可选性,因此您只需修复声明:
let r:Result<String> = Result<String>.Success("A-Ok")
let d = Result<String>.Success("Error")
let result = r ?? d