swift - 类型约束的可选扩展对其他类型可见

标签 swift generics option-type

所以因为我厌倦了必须手动 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/

相关文章:

string - Swift:获取字符串中子字符串开头的索引

ios - Swift -- 录音机/变声器应用程序 : How are these functions related?

java - 关于 Java 中具体化泛型的任何消息?

java - 为什么这种在 Java 数组中查找最大数组的通用方法无法编译?

kotlin - sumByDouble 需要 Double 找到 Double?

swift - :url loads url content of a truncated URL 的内容

ios - Alamofire laravel 中字符 0 周围的无效值

C# 泛型类类型参数(无法隐式转换)

java - Groovy 在 Java 可选上同时运行 map 和 orElseGet

java - 什么是惯用的 "functional"方法来获取 Optional<String> 并在 null 或空时返回默认字符串,否则返回修改后的字符串?