【问题标题】:Type-Constrained Optional Extension visible to other types其他类型可见的类型约束可选扩展
【发布时间】:2018-11-20 11:09:26
【问题描述】:

因此,因为我厌倦了必须手动 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 并得到以下错误之一:

对成员“orZero”的模糊引用
'细绳?'不能转换为“可选”

我想知道为什么 Xcode 会提供 .orZero 属性作为可选的有效自动完成选项?我原以为通用约束会阻止我看到它们。
不管怎样,我使用的是 Xcode 10.1 和 Swift 4.2

【问题讨论】:

    标签: swift generics optional


    【解决方案1】:

    .orZero 作为自动完成提供是一个错误。可以通过根据适当的文字协议重写扩展来规避它。

    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'

    【讨论】:

      【解决方案2】:

      看看this

      在您的扩展中,.orZero 仅适用于 Int、Float、Double。

      对于字符串,你有 .orEmpty。

      【讨论】:

      • 感谢您的回复,德里克!我知道上述可选扩展的类型限制。我的问题是关于为什么 Xcode 向我显示错误的属性作为自动完成建议。我将更新问题以更倾斜地概述这一点。
      猜你喜欢
      • 2020-05-27
      • 2022-09-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多