如何添加可选的字符串扩展名?

vol*_*ron 61 swift swift-extensions

您可以像这样创建一个String扩展:

extension String {
   func someFunc -> Bool { ... }
}
Run Code Online (Sandbox Code Playgroud)

但是如果你想将它应用于可选字符串呢?

var optionalString :String? = ""
optionalString!.someFunc() /* String? does not have a member someFunc */
Run Code Online (Sandbox Code Playgroud)

Vla*_*tko 153

在Swift 3.1中,您还可以为可选值添加扩展:

extension Optional where Wrapped == String {
  var isBlank: Bool {
    return self?.isBlank ?? true
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 这应该是新接受的答案. (4认同)
  • 用法是`myOptionalString.isBlank`.没有`?`,因为你在可选项本身而不是在`String`上调用它. (3认同)
  • `if myOptionalString?.isBlank {` 给出可选类型 Bool 的值?还没解开。 (2认同)

Dan*_*hin 12

你可以这样做:

protocol OptionalType { typealias A; var opt: A? { get } }
extension Optional: OptionalType { var opt: A? { return self } }

protocol StringType { var get: String { get } }
extension String: StringType { var get: String { return self } }

extension Optional where Wrapped: StringType {
  func getOrElse(s: String) -> String {
    return self.opt?.get ?? s
  }
}
Run Code Online (Sandbox Code Playgroud)

和:

let optStr: String? = nil
optStr.getOrElse("hello world")
Run Code Online (Sandbox Code Playgroud)

你不能约束Optional或者String那个问题的原因是因为它们是struct.通过为每个伪协议制定,现在我们可以根据自己的喜好进行约束.

我觉得swift已经放弃了很多东西,只是为了让初学者更容易学习,或者语言还不够成熟.


Mob*_*Dan 7

Optional对此的扩展返回aString

从Swift 3开始,您无法直接将扩展方法约束为可选方法String.Daniel Shin的回答解释说,您可以通过协议获得相同的结果.

但是,您可以在任意类型的Optional上创建扩展方法,并且我发现了一些具有String返回值的有用方法.这些扩展有助于将值记录到控制台.String当我想用空字符串替换可能的nil时,我在可选项上使用了asStringOrEmpty().

extension Optional {
    func asStringOrEmpty() -> String {
        switch self {
            case .some(let value):
                return String(describing: value)
            case _:
                return ""
        }
    }

    func asStringOrNilText() -> String {
        switch self {
            case .some(let value):
                return String(describing: value)
            case _:
                return "(nil)"
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

示例使用:

var booleanValue: Bool?
var stringValue: String?
var intValue: Int?

print("booleanValue: \(booleanValue.asStringOrNilText())")
print("stringValue: \(stringValue.asStringOrNilText())")
print("intValue: \(intValue.asStringOrNilText())")

booleanValue = true
stringValue = "text!"
intValue = 41

print("booleanValue: \(booleanValue.asStringOrNilText())")
print("stringValue: \(stringValue.asStringOrNilText())")
print("intValue: \(intValue.asStringOrNilText())")
Run Code Online (Sandbox Code Playgroud)

控制台输出:

booleanValue: (nil)
stringValue: (nil)
intValue: (nil)

booleanValue: true
stringValue: text!
intValue: 41
Run Code Online (Sandbox Code Playgroud)

 

Optional 不同于零指针

这些扩展说明了一个Optional与nil指针不同的东西.An Optionalenum指定类型(Wrapped)的一个,表示它包含或不包含值.您可以在Optional"容器" 上编写扩展名,即使它可能不包含值.

摘自Swift Optional Declaration

enum Optional<Wrapped> : ExpressibleByNilLiteral {

    /// The absence of a value.
    case none

    /// The presence of a value, stored as `Wrapped`.
    case some(Wrapped)

    ...
}
Run Code Online (Sandbox Code Playgroud)

在代码中,缺少值通常使用nil文字而不是显式.none枚举情况编写.


cau*_*jun 6

在 Swift 4.1 中,我遇到了Optional is ambiguous for type lookup in this context构建错误。要修复,您必须显式地将 Swift 命名空间添加到类型中:

extension Swift.Optional where Wrapped == String {
    var isBlank: Bool {
        return self?.isBlank ?? true
    }
}
Run Code Online (Sandbox Code Playgroud)


dhe*_*eru 5

extension Optional where Wrapped == String {
    var isNil: Bool {
        return self == nil
    }
}
Run Code Online (Sandbox Code Playgroud)

@Vlad Hatko 写的上述答案工作正常,但在 Swift 4 中存在一些问题,所以我将其更改为这个。