Does Swift have a null coalescing operator and if not, what is an example of a custom operator?

后端 未结 6 2207
醉酒成梦
醉酒成梦 2020-12-09 14:24

A common feature in many languages, the Null Coalescing Operator, is a binary operator often used to shorten expressions of the type:

x = possiblyNullValue N         


        
相关标签:
6条回答
  • 2020-12-09 15:04

    (Also see blog post)

    No, Swift doesn't currently support a null coalescing operator.

    Defining Custom Null Coalescing Operator for Swift

    A custom operator can be defined for Swift, with the following considerations regarding the Swift language:

    Swift and Nil

    Swift supports a null concept through its Optional type (a Discriminated Union of sorts) which either holds a value of the underlying type or no value (indicated by nil) and must be explicitly defined as being optional:

    var a : String?
    

    A non-optional type can never be nil, or assigned nil. Therefore a custom infix binary NCO can be expected to take an optional as its first parameter.

    Available Characters for Custom Operators in Swift

    In Swift, custom operators can be comprised of the following characters only:

    / = - + * % < > ! & | ^ . ~
    

    The Operator

    Given the choice of available characters, ||| (three pipes, no spacing) isn't terrible (similar to the double pipe OR in Javascript which is used like a NCO):

    Using the Operator

    var a = String?
    var z = a ||| "it's nil!"
    println(z) //Output: it's nil!
    

    Defining the Operator

    operator infix ||| {}
    
    @infix func |||<T> (left: T?, right: T) -> T  {
      if let l = left { return l }
      return right
    }
    
    0 讨论(0)
  • 2020-12-09 15:06

    As of Swift 2.2 (Xcode 6, beta 5) it's ??

    var x: Int?
    var y: Int? = 8
    
    var z: Int = x ?? 9000
    // z == 9000
    
    z = y ?? 9001
    // z == 8
    

    a ?? b is equivalent to the following code:

    a != nil ? a! : b
    

    And as of Beta 6, you can do this:

    x ?? y ?? 1 == 8
    
    0 讨论(0)
  • 2020-12-09 15:06

    What Venkat says is correct: there is none but you can define one. His implementation however is not ideal because he forgot to use @auto_closure.

    Also I believe you can overload || without needing to define a new operator.

    I do not have the compiler here, but I'll try to give you the code from memory:

    func |||<T> (maybe: Optional<T>, defaultValue: @auto_closure () -> T) -> T {
        if let some = maybe { 
          return some 
        }
        return defaultValue()
    }
    

    Edit: Thanks to Martin R for testing this with the compiler. See the comments. Apparently overloading || is possible but may not work as expected because of the way Swift handles resolution of overloaded operators (which is undocumented and therefore I have no idea if it can be worked around or not). I've changed the function above to use |||.

    0 讨论(0)
  • 2020-12-09 15:11

    hope this will help you

    1. yes , Now it is added in swift

    2. little Explanation

             var anumber:Int? = someValue
             var banumber = 2
             anumber =   ( anumber != nil) ? anumber : banumber ------- (a)
             println(anumber!)
      

    now instead of writing all (a) this we can just use this ->

            anumber = anumber ?? banumber
    

    and

    The operator can also be used multiple times in the same expression. like

         firstNumber ?? secondNumber ?? thirdNumber. 
    
    0 讨论(0)
  • 2020-12-09 15:24

    I blogged about a custom operator function that provides nil-coalescing here: http://ijoshsmith.com/2014/07/24/nil-coalescing-operator-in-swift/

    My choice of operator was !! which combines the logical not operator (!) and the unwrap operator (!) for a "if cannot unwrap" semantic. Seems I was late to the party, given this thread is already over a month old. Either way, here's my implementation in case you're interested...

    operator infix !! {}
    
    @infix func !! <T> (
        value: T?,
        defaultValue: @auto_closure () -> T)
        -> T
    {
        return value ? value! : defaultValue()
    }
    
    0 讨论(0)
  • 2020-12-09 15:24

    You can check with playground code below.

    import UIKit
    var personalSite : String?
    let defaultSite = "http://www.google.com"
    
    var website = personalSite ?? defaultSite
    
    0 讨论(0)
提交回复
热议问题