Swift 可选类型:.None == nil 的工作原理
Swift Optional type: how .None == nil works
我正在尝试了解它是如何工作的:
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: ())
}
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".
进行比较
我正在尝试了解它是如何工作的:
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: ())
}
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".