Swift可选类型:如何.None == nil有效

时间:2015-10-19 08:10:43

标签: swift optional

我试图了解它是如何运作的:

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

为什么.None相等nil

我在枚举定义中没有看到任何关于它的内容:

public enum Optional<Wrapped> : _Reflectable, NilLiteralConvertible {
    case None
    case Some(Wrapped)
    /// Construct a `nil` instance.
    public init()
    /// Construct a non-`nil` instance that stores `some`.
    public init(_ some: Wrapped)
    /// If `self == nil`, returns `nil`.  Otherwise, returns `f(self!)`.
    @warn_unused_result
    @rethrows public func map<U>(@noescape f: (Wrapped) throws -> U) rethrows -> U?
    /// Returns `nil` if `self` is nil, `f(self!)` otherwise.
    @warn_unused_result
    @rethrows public func flatMap<U>(@noescape f: (Wrapped) throws -> U?) rethrows -> U?
    /// Create an instance initialized with `nil`.
    public init(nilLiteral: ())
}

1 个答案:

答案 0 :(得分:12)

enum Optional符合NilLiteralConvertible协议, 这意味着它可以用“nil”文字初始化。 结果是Optional<T>.None,其中类型占位符T 必须从上下文中推断出来。

举个例子,

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

无法编译,但

let n : Int? = nil

,结果是Optional<Int>.None

现在,如果底层证券通常不能比较期权 类型不是Equatable

struct ABC { }

let a1 : ABC? = ABC()
let a2 : ABC? = ABC()

if a1 == a2 { } // binary operator '==' cannot be applied to two 'ABC?' operands

甚至不编译:

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

但这会编译:

if a1 == nil { } 

它使用运算符

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

其中_OptionalNilComparisonType未正式记录。 在https://github.com/andelf/Defines-Swift/blob/master/Swift.swift中 定义可以找到(由@rintaro和@Arsen找到,见评论):

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

这允许将任何可选类型与“nil”进行比较,无论基础类型是否为Equatable

简而言之 - 在Optional - nil的上下文中可以被视为.None的快捷方式,但具体类型必须从上下文中推断出来。有一个专用的==运算符可与“nil”进行比较。