Swift Optional type: how .None == nil works

后端 未结 1 1787
误落风尘
误落风尘 2021-01-12 19:06

I\'m trying to understand how does it work:

  1> func returnNone() -> String? { return .None }
  2> returnNone() == nil
$R0: Bool = true
  3> ret         


        
相关标签:
1条回答
  • 2021-01-12 19:52

    enum Optional conforms to the NilLiteralConvertible protocol, which means that it can be initialized with the "nil" literal. The result is Optional<T>.None where the type placeholder T must be inferred from the context.

    As an example,

    let n = nil // type of expression is ambiguous without more context
    

    does not compile, but

    let n : Int? = nil
    

    does, and the result is Optional<Int>.None.

    Now optionals can in general not be compared if the underlying type is not Equatable:

    struct ABC { }
    
    let a1 : ABC? = ABC()
    let a2 : ABC? = ABC()
    
    if a1 == a2 { } // binary operator '==' cannot be applied to two 'ABC?' operands
    

    and even this does not compile:

    if a1 == Optional<ABC>.None { } // binary operator '==' cannot be applied to two 'ABC?' operands
    

    But this compiles:

    if a1 == nil { } 
    

    It uses the operator

    public func ==<T>(lhs: T?, rhs: _OptionalNilComparisonType) -> Bool
    

    where _OptionalNilComparisonType is not documented officially. In https://github.com/andelf/Defines-Swift/blob/master/Swift.swift the definition can be found as (found by @rintaro and @Arsen, see comments):

    struct _OptionalNilComparisonType : NilLiteralConvertible {
      init(nilLiteral: ())
    }
    

    This allows the comparison of any optional type with "nil", regardless of whether the underlying type is Equatable or not.

    In short – in the context of Optionalnil can be thought of as a shortcut to .None, but the concrete type must be inferred from the context. There is a dedicated == operator for comparison with "nil".

    0 讨论(0)
提交回复
热议问题