看了 2016@Swift 大会视频(2) 超越OC与Swift间的鸿沟-付若愚,里面有两个关于 Optional 的例子,挺有意思。
第一个例子
原始代码:
var someArray: [Int];
someArray = [1, 2, 3]
var result = someArray.map({"No. \($0)"})
print(result) // ["No. 1", "No. 2", "No. 3"]
当 someArray 的类型变为 Optional<Array> 时,代码的结果发生了变化:
var someArray: [Int]?;
someArray = [1, 2, 3]
var result = someArray.map({"No. \($0)"})
print(result) // Optional("No. [1, 2, 3]")
付若愚就此引入了他的错误观点:
弱类型 -> 强类型
欢迎来到类型安全的世界
[⌘ + Click] -> [⌥ + Click]
Optional 不拆包,不符合编程规范
首先,付若愚的第二段代码是不符合编程规范的,调用 Optional 对象方法前,必须拆包:
var someArray: [Int]?;
someArray = [1, 2, 3]
var result = someArray!.map({"No. \($0)"})
print(result) // ["No. 1", "No. 2", "No. 3"]
Instance 仍然是 Instance,[⌘ + Click] 依然有用
其次,Objective-C 与 Swift 都是强类型的语言,前者声明变量时必须显示声明变量类型,后者在这个基础上增加了类型推断。
我们 [⌘ + Click] 点击原始代码中的 map 方法,可以看到,调用的是 Array 的 Map 方法:
extension CollectionType {
/// Returns an `Array` containing the results of mapping `transform`
/// over `self`.
///
/// - Complexity: O(N).
@warn_unused_result
public func map<T>(@noescape transform: (Self.Generator.Element) throws -> T) rethrows -> [T]
我们 [⌘ + Click] 点击第二段代码中的 map 方法,可以看到,调用的是 Optonal 的 Map 方法:
/// A type that can represent either a `Wrapped` value or `nil`, the absence
/// of a value.
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
public func map<U>(@noescape f: (Wrapped) throws -> U) rethrows -> U?
第二个例子
var dictionary: [String: String?] = [:]
dictionary = ["key": "value"]
func justReturnNil() -> Optional<String> {
return Optional<String>.None
}
dictionary["key"] = justReturnNil()
print(dictionary) // ["key": nil]
dictionary["key"] = nil
print(dictionary) // [:]
这仍然是一个 Optional 的例子,String? 本质上是 Optional<String>,justReturnNil
这个函数实际上是:
func justReturnNil() -> Optional<String> {
return Optional<String>.None
}
我们以这段代码,代替原始的函数代码,运行的结果不变。这本质上是 Swift 的语法糖。
Optional 的定义:
/// A type that can represent either a `Wrapped` value or `nil`, the absence
/// of a value.
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
public func map<U>(@noescape f: (Wrapped) throws -> U) rethrows -> U?
/// Returns `nil` if `self` is `nil`, `f(self!)` otherwise.
@warn_unused_result
public func flatMap<U>(@noescape f: (Wrapped) throws -> U?) rethrows -> U?
/// Create an instance initialized with `nil`.
public init(nilLiteral: ())
}