Swift 4新功能-4

八、泛型下标

下标现在可以有泛型参数和返回类型.
最权威的例子莫过于表示 JSON 数据: 你可以定义一个泛型下标来保持调用者期望类型的内容.

struct JSON {
    fileprivate var storage: [String:Any]

    init(dictionary: [String:Any]) {
        self.storage = dictionary
    }

    subscript(key: String) -> T? {
        return storage[key] as? T
    }
}

let json = JSON(dictionary: [
    "城市名": "北京",
    "国家代码": "cn",
    "人口": 21_710_000
    ])

// 没必要用 as? Int
let population: Int? = json["人口"]

另一个例子: Collection 的一个下标接受一个泛型索引序列, 并返回一个这些索引所在的数组:

extension Collection {
    subscript(indices: Indices) -> [Element] where Indices.Element == Index {
        var result: [Element] = []
        for index in indices {
            result.append(self[index])
        }
        return result
    }
}

let words = "我 思 故 我 在".split(separator: " ")
words[[1,2]]

九、NSNumber 桥接

修正部分危险行为当桥接Swift原生数字类型和NSNumber的时候.

import Foundation

let n = NSNumber(value: UInt32(301))
let v = n as? Int8 // nil(Swift 4). Swift 3会是45 (试试看!).

十、类和协议的组合

你现在能写出OC这段 UIViewController * 在Swift中的等价代码, 比如声明这样一个变量,这个变量拥有实体类型并同时遵守若干协议. 语法 let 变量: 某个类 & 协议1 & 协议2.

import Cocoa

protocol HeaderView {}

class ViewController: NSViewController {
    let header: NSView & HeaderView

    init(header: NSView & HeaderView) {
        self.header = header
        super.init(nibName: nil, bundle: nil)
    }

    required init(coder decoder: NSCoder) {
        fatalError("not implemented")
    }
}

// 不能传一个简单的NSView进去因为不遵守协议
//ViewController(header: NSView())
// 错误: argument type 'NSView' does not conform to     expected type 'NSView & HeaderView'

// 必须穿一个 NSView (子类) 同时遵守协议
extension NSImageView: HeaderView {}

ViewController(header: NSImageView()) // 有用

你可能感兴趣的:(Swift 4新功能-4)