所以因为我厌倦了必须手动 nil-coalesce 可选值,所以我决定将常见的默认值变成 Optional 上漂亮且易于使用的扩展,如下所示:
public extension Optional {
var exists: Bool { return self != nil }
}
public extension Optional where Wrapped == String {
var orEmpty: Wrapped { return self ?? "" }
}
public extension Optional where Wrapped == Int {
var orZero: Wrapped { return self ?? 0 }
}
public extension Optional where Wrapped == Double {
var orZero: Wrapped { return self ?? 0 }
}
public extension Optional where Wrapped == Float {
var orZero: Wrapped { return self ?? 0 }
}
public extension Optional where Wrapped == Bool {
var orFalse: Wrapped { return self ?? false }
}
当我尝试在具有特定类型的可选值上使用这些时,我的问题就来了。
我可以在 String?
类型的变量上调用 .orZero
并得到以下错误之一:
Ambiguous reference to member 'orZero'
'String?' is not convertible to 'Optional'
我想知道为什么 Xcode 提供这样一个可选的 .orZero
属性作为有效的自动完成选项?我原以为通用约束会阻止我看到它们。
不管怎样,我使用的是 Xcode 10.1 和 Swift 4.2
最佳答案
.orZero
作为自动完成提供是一个错误。它可以通过根据适当的文字协议(protocol)重写您的扩展来规避。
public extension Optional where Wrapped: ExpressibleByIntegerLiteral {
var orZero: Wrapped { return self ?? 0 }
}
public extension Optional where Wrapped: ExpressibleByBooleanLiteral {
var orFalse: Wrapped { return self ?? false }
}
以这种方式表达,Swift 现在可以弄清楚 .isZero
不应该被建议,即 String?
类型的变量,如果您尝试调用无论如何,它都会给出错误 Type 'String' does not conform to protocol 'ExpressibleByIntegerLiteral'
。
关于swift - 类型约束的可选扩展对其他类型可见,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53391691/