Swift: Optional 的本质是枚举

作者: 公爵海恩庭斯 | 来源:发表于2016-03-30 14:34 被阅读348次

看了 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: ())
}

相关文章

网友评论

    本文标题:Swift: Optional 的本质是枚举

    本文链接:https://www.haomeiwen.com/subject/yptelttx.html