How to add an optional string extension?

后端 未结 9 520
佛祖请我去吃肉
佛祖请我去吃肉 2020-12-13 23:44

You can create a String extension like so:

extension String {
   func someFunc -> Bool { ... }
}

but what if you want it to apply to opt

相关标签:
9条回答
  • 2020-12-14 00:08

    found some trick swift 3

    class A{
        var name:String!;
        init(_ name:String?){
            self.name = name;
        }
    }
    
    extension Optional where Wrapped == String {
        func compareText(_ other:String?)->Bool{
            switch (self,other){
            case let(a?,b?):
                return a < b;
            case (nil,_):
                return true;
            default:
                return false;
            }
        }
    }
    
    let words:[A] = [A("a"),A(nil),A("b"),A("c"),A(nil)];
    
    // let sorted = words.sorted{ 0.name.compareText($1.name) }
    // trick
    let sorted = words.sorted{ ($0.name as String?).compareText($1.name) }
    
    print(sorted.map{$0.name});
    
    0 讨论(0)
  • 2020-12-14 00:09
    extension Optional where Wrapped == String {
    var isNil: Bool {
        return self == nil
    }
    

    The above answer(written by @Vlad Hatko) works fine but in swift 4 there are some issues, so I changed it to this.

    0 讨论(0)
  • 2020-12-14 00:11

    Update: For a workaround that works with Swift 2 and above, see Daniel Shin’s answer


    An optional String isn't in and of itself a type, and so you cannot create an extension on an optional type. In Swift, an Optional is just an enum (plus a bit of syntactic sugar) which can either be None, or Some that wraps a value. To use your String method, you need to unwrap your optionalString. You can easily use optional chaining to achieve this:

    optionalString?.someFunc()
    

    If optionalString is not nil, someFunc will be called on it. An alternative (less concise) way of doing this is to use optional binding to establish whether or not optionalString has a value before trying to call the method:

    if let string = optionalString {
        string.someFunc()    // `string` is now of type `String` (not `String?`)
    }
    

    In your example from the comments below, you needn't nest multiple if statements, you can check if the optional string is an empty string in a single if:

    if optionalString?.isEmpty == true {
        doSomething()
    }
    

    This works because the expression optionalString?.isEmpty returns an optional Bool (i.e. true, false or nil). So doSomething() will only be called if optionalString is not nil, and if that string is empty.

    Another alternative would be:

    if let string = optionalString where string.isEmpty {
        doSomethingWithEmptyString(string)
    }
    
    0 讨论(0)
  • 2020-12-14 00:12

    Extensions on Optional that return a String

    As of Swift 3, you cannot directly constrain an extension method to an optional String. You can achieve the equivalent result with protocols as Daniel Shin's answer explains.

    You can however, create an extension method on an Optional of any type and I've found some useful methods that have a String return value. These extensions are helpful for logging values to the console. I've used asStringOrEmpty() on a String optional when I want to replace a possible nil with empty string.

    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)"
            }
        }
    }
    

    Example Use:

    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())")
    

    Console Output:

    booleanValue: (nil)
    stringValue: (nil)
    intValue: (nil)
    
    booleanValue: true
    stringValue: text!
    intValue: 41
    

     

    Optional different than nil pointer

    These extensions illustrate that an Optional is different that a nil pointer. An Optional is a enum of a specified type (Wrapped) which indicates that it does or does not contain a value. You can write an extension on the Optional "container" even though it may not contain a value.

    Excerpt from 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)
    
        ...
    }
    

    In code, the absence of a value is typically written using the nil literal rather than the explicit .none enumeration case.

    0 讨论(0)
  • 2020-12-14 00:14

    You can create an optional string extension. I did the following to set an optional string to empty if it was nil :

    extension Optional where Wrapped == String {
    
        mutating func setToEmptyIfNil() {
            guard self != nil else {
                self = ""
                return
            }
        }
    
    }
    
    0 讨论(0)
  • 2020-12-14 00:19

    In Swift 4.1 I was getting a Optional is ambiguous for type lookup in this context build error. To fix, you have to explicitly add the Swift namespace to the type:

    extension Swift.Optional where Wrapped == String {
        var isBlank: Bool {
            return self?.isBlank ?? true
        }
    }
    
    0 讨论(0)
提交回复
热议问题