美文网首页
Swift4 新功能

Swift4 新功能

作者: xukuangbo_ | 来源:发表于2017-09-18 11:00 被阅读85次

    swift4新功能

    内容

    开区间

    字符

    同 件内的扩展,私有声明可

    智能Key path

    编码和解码

    协议相关类型的约束字典(Dictionary)和集合(Set)的增强MutableCollection.swapAt法reduce和inout

    泛型下标

    NSNumber桥接

    类和协议的组合

    开区间

    SE-0172带来 种新的RangeExpression协议和 组前缀/后缀操作符给开区间.比如现在区间

    论是上界还是下界都可以不指定.

    限序

    你可以 开区间来造 个 限序,对 期使enumerated()法的同学来说,这是 个福,尤

    其是当你不想序号从0开始的时候:

    let字 表= ["a","b","c","d"]

    let加序号的字 表= zip(1...,字 表)

    Array(加序号的字 表)集合的下标

    在集合的下标中 开区间的话,集合的startIndex or endIndex会“智能填充”缺失的那 边.

    let numbers = [1,2,3,4,5,6,7,8,9,10]

    numbers[5...]取代numbers[5..

    开区间可 于 式匹配,比如 个switch语 中case表达式.不过,编译器好像还不能(暂时?)判

    定switch已被穷尽.

    let value = 5

    switch value {

    case 1...:

    print("于0")

    case 0:

    print("0")

    case ..<0:

    print("于0")

    default:

    fatalError("不可到达")

    }

    字符

    多 字符 字

    SE-0168带来 种简洁定义多 字符 的语法,使(""").在 个多 字符  并不需要写转义字

    符,也就是说 多数 本格式(如JSON或HTML)就可以直接粘贴  须任何转义.结尾三引号的

    缩进,决定 每  头部被裁剪的空格多少. Python:致敬我吗Kotlin:我也早有这功能

    let多 字符= """

    这是 个多 字符.不需要在这 转义"引号".结尾三引号的位置,控制空格的裁剪数.

    """

    print(多 字符)

    可以打开控制台(菜单View > Debug Area > Activate Console)来看print的输出.

    字符"双"变回 个Collection,没错,天地暂停,时光倒流

    SE-0163是Swift 4字符 模型的第 部分修正.最 变化String再度是 个Collection (因为在Swift 1.x中是这样的),比如String.CharacterView已经被并入其 类型中. (其他view,

    UnicodeScalarView, UTF8View,和UTF16View,依旧存在.)

    注意SE-0163还没完全实现并且这条建议中还有很多字符 相关的提议(意思是还有的折腾).

    let欢迎语= "侬好Bobo, !"不需要再钻到.characters属性  去

    欢迎语.count

    for字in欢迎语{

    print(字)

    }

    Substring是字符 切片后的新类型

    字符 切片现在是Substring类型的实. String和Substring两者都遵从StringProtocol.乎所

    有字符API都在StringProtocol所以String和Substring为很 程度是 样的.

    let逗号的位置=欢迎语.index(of: ",")!

    let substring =欢迎语[..<逗号的位置]

    type(of: substring)

    Substring可以调String的API

    print(substring.uppercased())

    Unicode 9

    Swift 4即将 持Unicode 9,当前正在修正  些时髦emoji适当的语义问题.下 的所有字符计数

    是1,和实际的对比:

    "".count+肤"".count有4个成员的家庭

    "\u{200D}\u{200D}\u{200D}".count家庭+肤"".count+肤+职业Character.unicodeScalars属性

    现在可以直接访问 个Character的unicode编码值,不 先转成String (SE-0178):

    let c: Character = ""

    Array(c.unicodeScalars)同 件内的扩展,私有声明可

    SE-0169改 访问控制规则,比如在同 件内的扩展中,原类型的private声明也是可 的.这种改

    进可让同 件内保持使private分割类型定义成为可能,减少不受欢迎的fileprivate关键词的使.

    struct SortedArray {

    private var storage: [Element] = []init(unsorted: [Element]) {

    storage = unsorted.sorted()

    }

    }

    extension SortedArray {

    mutating func insert(_ element: Element) {

    storage此处可storage.append(element)

    storage.sort()

    }

    }

    let array = SortedArray(unsorted: [3,1,2])

    storage此处不可(不像fileprivate)

    array.storage error: 'storage' is inaccessible due to 'private' protection level智能key path

    SE-0161描述的新式key path有可能搞 个Swift 4的 新闻.不像Cocoa中基于字符 的那样too

    simple, Swift中的可是强类型的,你们要认真学习.

    struct{

    var名字: String

    }

    struct书{

    var标题: String

    var作者: []

    var第 作者:{

    return作者.first!

    }

    }

    let Vergil =(名字: "Vergil")

    let Xernaga =(名字: "Xernaga")

    let Kotlin快速入 书=书(标题: "Kotlin快速入",作者: [Vergil, Xernaga])

    Key path由 个根类型开始,和其下任意深度的属性链和下标名组成.

    你可以写 个key path由 个反斜杠开始: \书.标题.每个类型 动获取 个[keyPath: ...]下标可

    以设置或获取指定key path的值.

    Kotlin快速入 书[keyPath: \书.标题]

    Key path可深入并 持计算属性

    Kotlin快速入 书[keyPath: \书.第 作者.名字]

    Key path是可被存储和操作的对象.比如,你可以给 个key path加上额外字段深入到作者.

    let作者KeyPath = \书.第 作者

    type(of:作者KeyPath)

    let名字KeyPath =作者KeyPath.appending(path: \.名字)可以省 类型名,如果编译器能推断的话

    Kotlin快速入 书[keyPath:名字KeyPath]

    下标Key path

    Key paths也 持下标.如此 来可以非常 捷的深入到数组或字典这些集合类型中.不过这功能

    在当前snapshot还未实现.

    压缩化 和 序 化

    SE-0166: Swift Archival & Serialization定义  种为任意Swift类型(class, struct,和enum)来描

    述  如何压缩和序 化的 法.类型可遵从Codable协议让  可(解)压缩.多数情况下添加Codable协议就可以让你的 定义类型完美解压缩,因为编译器可以 成 个

    默认的实现,前提是所有成员类型都是Codable的.当然你可以覆盖默认 法如果需要优化 定义

    类型的编码.这个说来话—还请研读SE-0166.

    遵从Codable协议,让 个 定义类型(和其所有成员)可压缩struct扑克: Codable {

    enum全部花: String, Codable {

    case桃,花,红,片

    }

    enum全部点数: Int, Codable {

    case尖= 1,,三,四,五,六,七,八,九,,钩,蛋,老K

    }

    var花:全部花

    var点数:全部点数}

    let我的牌= [扑克(花: .桃,点数: .尖),扑克(花: .红,点数: .蛋)]编码

    旦有 个Codable值,你要把它传递给 个编码器以 压缩.

    Codable协议的基础设施可以写  的编解码器,不过Swift同时为JSON提供 个内置的编解

    码器(JSONEncoder和JSONDecoder)和属性 表(PropertyListEncoder和PropertyListDecoder).这些是在SE-0167中定义的. NSKeyedArchiver同样 持所有的Codable类型.

    import Foundation

    var encoder = JSONEncoder()

    JSONEncoder提供的可定制化属性encoder.dataEncodingStrategy

    encoder.dateEncodingStrategy

    encoder.nonConformingFloatEncodingStrategy

    encoder.outputFormatting = .prettyPrinted格式化的json字符encoder.userInfo

    let jsonData = try encoder.encode(我的牌)

    String(data: jsonData, encoding: .utf8)

    解码

    let decoder = JSONDecoder()

    let decoded = try decoder.decode([扑克].self, from: jsonData)协议相关类型的约束

    SE-0142:协议的相关类型可以where语 约束.看似  步,却是类型系统表达能 的  步,让

    标准库可以 幅简化.喜 普奔的是, Sequence和Collection在Swift 4中 上这个就 直观.

    Sequence.Element

    Sequence现在有  的相关类型Element .原先Swift 3中到处露脸的Iterator.Element ,现在

    瘦 成Element:

    extension Sequence where Element: Numeric {

    var求和: Element {

    var结果: Element = 0

    for单个元素in self {结果+=单个元素

    }

    return结果}

    }

    [1,2,3,4].求和

    当扩展Sequence和Collection时所需约束 少

    在Swift 3时代,这种扩展需要很多的约束:

    extension Collection where Iterator.Element: Equatable,

    SubSequence: Sequence,

    SubSequence.Iterator.Element == Iterator.Element

    在Swift 4,编译器已经提前知道 上述3个约束中的2个,因为可以 相关类型的where语 来表

    达它们.

    extension Collection where Element: Equatable {

    func头尾镜像(_ n: Int) Bool {

    let头= prefix(n)

    let尾= suffix(n).reversed()

    return头.elementsEqual(尾)

    }

    }

    [1,2,3,4,2,1].头尾镜像(2)

    字典(Dictionary)和 集合(Set)的增强

    SE-0165加  些很奶死的Dictionary和Set增强.基于序(Sequence)的构造器

    从 个键值对序 构造字典.

    let热 编程语= ["Swift", "Python", "Kotlin"]

    let热 编程语 排= Dictionary(uniqueKeysWithValues: zip(1...,热 编程语))热 编程语 排[2]

    合并(merge)构造器& merge法

    当从 个序 构造字典,或把 个序 合并到字典中,描述如何处 重复的键.

    let热 技术= [("苹果", "Swift"), ("歌", "TensorFlow"), ("苹果", "Swift Playgrouds"),

    ("苹果", "ARKit"), ("歌", "TensorFlowLite"),("歌", "Kotlin"),("苹果", "Core ML")]

    let商= Dictionary(热 技术, uniquingKeysWith: { (第,最后) in最后})

    合并构造器或merge法遇到 个字典时就没那么舒服.因为字典的元素类型是 个 带标签的

    元组型(key: Key, value: Value)但上述2个 法却要求 个  标签的 元组型(Key, Value),不得已

    要  转换.希望这个今后能完善.SR-922和SR-4969.

    let默认设置= ["动登录": false, "已绑定 机": false, "蓝牙开启": false]

    var户设置= ["动登录": true, "已绑定 机": false]

    会产  个烦 的类型转换警告

    let合并的设置=户设置.merge(默认设置) { (old, _) in old }

    只能使 以下替代:

    户设置.merge(默认设置.map { $0 }) { (old, _) in old }户设置

    下标的默认值

    你现在可以给下标中加 个默认值参数,当key不存在时会返回这个值,这样 可让返回类型非Optional.

    热 编程语 排[4, default: "(未知)"]

    /*:在你想通过下标 新 个值时,这个功能就非常有:

    */

    import Foundation

    var词组= """

    天姥连天向天横 势拔五岳掩 城

    天台四万八千丈 对此欲倒东南倾

    我欲因之梦吴越  夜 度镜湖

    湖 照我影 送我 剡溪

    """

    var出现频率: [Character: Int] = [:]

    for词in词组.components(separatedBy: .whitespacesAndNewlines).joined() {

    出现频率[词, default: 0] += 1

    }

    for (词,次数) in出现频率{

    if次数> 1 {

    print(词,次数)

    }

    }

    Dictionary相关的map和filter

    filter返回 个Dictionary非Array.相似的,新 法mapValues转换值的同时保持字典结构.

    let filtered =热 编程语 排.filter {

    $0.key % 2 == 0

    }

    type(of: filtered)

    let mapped =热 编程语 排.mapValues { value in

    value.uppercased()

    }

    mapped

    Set.filter现在同样返回 个Set不是Array.

    let set: Set = [1,2,3,4,5]

    let filteredSet = set.filter { $0 % 2 == 0 }type(of: filteredSet)

    分组 个序

    把 个序 分成 组,比如联系 按姓分组.

    let联系= ["张三丰", "李思思", "张素芳", "李", "王", "张 军"]

    let通讯录= Dictionary(grouping:联系, by: { $0.first! })

    通讯录

    SE-0173介绍  种交换 个集合中两个元素的新 法.与既有的swap(::)法不同, swapAt(::)接受 个要交换的元素切片,不是整个元素本(通过inout参数).

    加这个的 的是swap法带2个inout参数 不再兼容新的独占式内存访问规则,SE-0176.既有

    的swap(::)法不能再交换同 个集合中的两个元素.

    var numbers = [1,2,3,4,5]

    numbers.swapAt(0,1)

    Swift 4中非法swap(&numbers[3], &numbers[4])numbers

    reduce和inout

    SE-0171新增reduce的 个变体,让部分结果以inout传递给组合函数.如此 来可以通过消除

    中间结果的副本来递增 个序,幅提升reduce算法的性能.

    SE-0171为实现.

    尚未实现

    extension Sequence where Element: Equatable {

    func uniq() [Element] {

    return reduce(into: []) { (result: inout [Element], element) in

    if result.last != element {

    result.append(element)

    }

    }

    }

    }

    [1,1,1,2,3,3,4].uniq()

    泛型下标

    托SE-0148的福,下标现在可以有泛型参数和返回类型.

    最权威的  莫过于表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桥接

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

    import Foundation

    let n = NSNumber(value: UInt32(301))

    let v = n as? Int8 nil(Swift 4). Swift 3会是45 (试试看!).

    类和协议的组合

    SE-0156:你现在能写出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())有

    相关文章

      网友评论

          本文标题:Swift4 新功能

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