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

Swift 4 新功能 -(二)

  1. 协议相关类型的约束
  2. 字典(Dictionary)和集合(Set)的增强
  3. MutableCollection.swapAt 方法
  4. reduce 和 inout
  5. 泛型下标
  6. NSNumber 桥接
  7. 类和协议的组合

协议相关类型的约束

SE-0142: 协议的相关类型可以用where语句约束. 看似一小步,却是类型系统表达能力的一大步,让标准库可以大幅简化. 喜大普奔的是, SequenceCollection 在Swift 4中用上这个就更直观了.

  • Sequence.Element

Sequence 现在有了自己的相关类型Element . 原先Swift 3中到处露脸的Iterator.Element , 现在瘦身成Element:

extension Sequence where Element: Numeric {
    var sum: Element {
        var result: Element = 0
        for item  in self {
            sum += item
        }
        return result
    }
}
[1,2,3,4].sum
  • 当扩展 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 prefieIsEqualSuffix(_ n: Int) -> Bool {
        let head = prefix(n)
        let suff = suffix(n).reversed()
        return head.elementsEqual(suff)
    }
}
[1,2,3,4,2,1]. prefieIsEqualSuffix(2)

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

SE-0165 加了一些很nice的 DictionarySet增强.

  • 基于序列(Sequence)的构造器

    从一个键值对序列构造字典.

let hotLanguage = ["Swift", "Python", "Kotlin","JAVA","C++"]
let hotLanguageRanking = Dictionary(uniqueKeysWithValues: zip(1..., hotLanguage))
hotLanguageRanking[2]
  • 合并(merge)构造器 & merge 方法
    当从一个序列构造字典,或把一个序列合并到字典中,描述如何处理重复的键.
let duplicates = [("a", 1), ("b", 2), ("a", 3), ("b", 4)]
let letters = Dictionary(duplicates, uniquingKeysWith: { (first, _) in first })
>>> letters = ["b": 2, "a": 1]

合并构造器或 merge 方法遇到一个字典时就没那么舒服了. 因为字典的元素类型是一个 带标签的 元组型(key: Key, value: Value)但上述2个方法却要求一个 无标签的 元组型(Key, Value), 不得已要手工转换. 希望这个今后能完善. 见 SR-922 SR-4969.

let defaults = ["foo": false, "bar": false, "baz": false]
var options = ["foo": true, "bar": false]
// 会产生一个烦人的类型转换警告 
// error: error: generic parameter 'S' could not be inferred
options.merge(defaults) { (old, _) in old }
// 替代方法
 options.merge(defaults.map { $0 }) { (old, _) in old }
  • 下标的默认值

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

hotLanguage[4, default: "(unknown)"]

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

let source = "how now brown cow"
var frequencies: [Character: Int] = [:]
for c in source {
    frequencies[c, default: 0] += 1
}
frequencies

var words = """
    天姥连天向天横 势拔五岳掩赤城
    天台四万八千丈 对此欲倒东南倾
    我欲因之梦吴越 一夜飞度镜湖月
    湖月照我影 送我至剡溪
    """
var frequencies: [Character: Int] = [:]
for word in words.components(separatedBy: .whitespacesAndNewlines).joined() {
    frequencies[word, default: 0] += 1
}
for (word , count) in frequencies {
    if count > 1 {
        print(word, count)
    }
}
  • Dictionary相关的 map 和 filter

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

let filtered = hotLanguageRaking.filter {
    $0.key % 2 == 0
}
type(of: filtered)

let mapped = hotLanguageRanking.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 contacts = ["Julia", "Susan", "John", "Alice", "Alex"]
let grouped = Dictionary(grouping: contacts, by: { $0.first! })
>>> grouped = ["J": ["Julia", "John"], "S": ["Susan"], "A": ["Alice", "Alex"]]

MutableCollection.swapAt 方法

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()

Swift 4 新功能 -(一)

英文 By Ole Begemann 中文 by 小波
相关视频

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

推荐阅读更多精彩内容