Whatʼs new in Swift 4 (Swift 4新功能)

Swift 4 新功能 -(一)

  1. 开区间
  2. 字符串
  3. 同文件内的扩展, 私有声明可见
  4. 智能Key path
  5. 编码和解码

开区间

SE-0172 带来一种新的 RangeExpression 协议和一组前缀/后缀操作符给开区间. 比如现在区间无论是上界还是下界都可以不指定.

  • 无限序列

    你可以用开区间来造一个无限序列, 对长期使用 enumerated() 方法的同学来说,这是一个福音,尤其是当你不想序号从0开始的时候:

let letters = ["a","b","c","d"]
let numberedLetters = zip(1..., letters)
Array(numberedLetters)
  • 集合的下标

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

let numbers = [1,2,3,4,5,6,7,8,9,10]
numbers[5...] // 取代 numbers[5..<numbers.endIndex]
打印 [6, 7, 8, 9, 10]
  • 方式匹配

开区间可用于方式匹配, 比如一个 switch 语句中case 表达式 .

let value = 5
switch value {
case 1...:
    print("greater than zero")
case 0:
    print("zero")
case ..<0:
    print("less than zero")
default:
    fatalError("unreachable")
}
打印 "greater than zero"

字符串

  • 多行字符串字面量

SE-0168 带来一种简洁定义多行字符串的语法,使用 ("""). 在一个多行字符串里并不需要写转义字符, 也就是说大多数文本格式 (如JSON 或 HTML) 就可以直接粘贴而无须任何转义. 结尾三引号的缩进,决定了每一行头部被裁剪的空格多少.

let multilineString = """
    This is a multi-line string.
    You don't have to escape "quotes" in here.
    The position of the closing delimiter
      controls whitespace stripping.
    """
print(multilineString)
打印
This is a multi-line string.
You don't have to escape "quotes" in here.
The position of the closing delimiter
  controls whitespace stripping.
  • 字符串"又双"变回一个 Collection了
    SE-0163Swift 4 字符串模型的第一部分修正. 最大变化 String 再度是一个 Collection (因为在Swift 1.x中是这样的), 比如 String.CharacterView 已经被并入其父类型中. (其他view, UnicodeScalarView, UTF8View, 和 UTF16View, 依旧存在.)

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

let greeting = "Hello, 😜!"
// No need to drill down to .characters
greeting.count
for char in greeting {
    print(char)
}
  • Substring 是字符串切片后的新类型

字符串切片现在是 Substring类型的实例. StringSubstring 两者都遵从 StringProtocol. 几乎所有字符串API都在StringProtocol 所以 StringSubstring 行为很大程度是一样的.

let comma = greeting.index(of: ",")!
let substring = greeting[..<comma]
type(of: substring)
// String API can be called on Substring
print(substring.uppercased())
  • Unicode 9

Swift 4 即将支持 Unicode 9, 当前正在修正 一些时髦emoji适当的语义问题. 下面的所有字符计数是 1, 和实际的对比:

"👧🏽".count // 人 + 肤色
"👨‍👩‍👧‍👦".count // 有4个成员的家庭
"👱🏾\u{200D}👩🏽\u{200D}👧🏿\u{200D}👦🏻".count // 家庭 + 肤色
"👩🏻‍🚒".count // 人 + 肤色 + 职业
  • Character.unicodeScalars 属性

现在可以直接访问一个 Characterunicode编码值,而不用先转成String (SE-0178):

let c: Character = "🇪🇺"
Array(c.unicodeScalars)
 结果: [127466, 127482]
  • 同文件内的扩展, 私有声明可见

SE-0169 更改了访问控制规则,比如在同文件内的扩展中,原类型的private声明也是可见的. 这种改进可让同文件内保持使用private分割类型定义成为可能 , 减少不受欢迎的fileprivate关键词的使用.

struct SortedArray<Element: Comparable> {
    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 Person {
    var name: String
}

struct Book {
    var title: String
    var authors: [Person]
    var primaryAuthor: Person {
        return authors.first!
    }
}

let abelson = Person(name: "Harold Abelson")
let sussman = Person(name: "Gerald Jay Sussman")
let sicp = Book(title: "Structure and Interpretation of Computer Programs", authors: [abelson, sussman])
  • Key path由一个根类型开始,和其下任意深度的属性链和下标名组成.

你可以写一个key path由一个反斜杠开始: \ Book.title. 每个类型自动获取一个 [keyPath: …] 下标可以设置或获取指定key path的值.

sicp[keyPath: \Book.title]
// Key paths can to drill down and work for computed properties
sicp[keyPath: \Book.primaryAuthor.name]

  • Key path 是可被存储和操作的对象. 比如, 你可以给一个key path加上额外字段深入到作者.
let authorKeyPath = \Book.primaryAuthor
type(of: authorKeyPath)
let nameKeyPath = authorKeyPath.appending(path: \.name) // you can omit the type name if the compiler can infer it
sicp[keyPath: nameKeyPath]
  • 下标Key path

Key paths 也支持下标. 如此一来可以非常便捷的深入到数组或字典这些集合类型中. 不过这功能在当前snapshot & xcode 9 beta还未实现.

//sicp[keyPath: \Book.authors[0].name]
// INTERNAL ERROR: feature not implemented: non-property key path component

压缩化 和 序列化

SE-0166: Swift Archival & Serialization 定义了一种为任意Swift类型 (class, struct, 和 enum) 来描述自身如何压缩和序列化的方法. 类型可遵从 Codable协议让自身可(解)压缩.

大多数情况下添加Codable 协议就可以让你的自定义类型完美解压缩, 因为编译器可以生成一个默认的实现,前提是所有成员类型都是Codable的. 当然你可以覆盖默认方法如果需要优化自定义类型的编码. 这个说来话长 — 还请研读SE-0166.

// Make a custom type archivable by conforming it (and all its members) to Codable
struct Card: Codable {
    enum Suit: String, Codable {
        case clubs, spades, hearts, diamonds
    }

    enum Rank: Int, Codable {
        case ace = 1, two, three, four, five, six, seven, eight, nine, ten, jack, queen, king
    }

    var suit: Suit
    var rank: Rank
}

let hand = [Card(suit: .clubs, rank: .ace), Card(suit: .hearts, rank: .queen)]
  • 编码

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

利用Codable协议的基础设施可以写自己的编解码器, 不过Swift同时为JSON提供一个内置的编解码器 (JSONEncoderJSONDecoder) 和属性列表 (PropertyListEncoderPropertyListDecoder). 这些是在 SE-0167 中定义的. NSKeyedArchiver 同样支持所有的 Codable 类型.

import Foundation

var encoder = JSONEncoder()

// JSONEncoder提供的可定制化属性
encoder.dataEncodingStrategy
encoder.dateEncodingStrategy
encoder.nonConformingFloatEncodingStrategy
encoder.outputFormatting
encoder.userInfo

let jsonData = try encoder.encode(hand)
String(data: jsonData, encoding: .utf8)

  • 解码
let decoder = JSONDecoder()
let decoded = try decoder.decode([Card].self, from: jsonData)
[{clubs, ace}, {hearts, queen}]

Swift 4新功能 二
英文 By Ole Begemann 中文 by 小波
相关视频

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,390评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,821评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,632评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,170评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,033评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,098评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,511评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,204评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,479评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,572评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,341评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,893评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,171评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,486评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,676评论 2 335

推荐阅读更多精彩内容