Swift Tips 001 - Namespacing with nested types

每天了解一点不一样的 Swift 小知识

代码截图

小笔记

嵌套类型是啥意思,怎么体现在这段代码里了

通俗的说,嵌套类型是指在某个类型中定义新的枚举,类或者结构体类型,这两个类型之间是嵌套的关系,关于嵌套类型的相关知识点可以参考 The Swift Programming Language 里的章节 - 嵌套类型

具体来说,要在一个类型中嵌套另一个类型,将嵌套类型的定义写在其外部类型的 {} 内,而且可以根据需要定义多级嵌套。

举个例子,下面的例子中,我们会说 Suit 是嵌套在 BlackjackCard 里的一个枚举类型,同理 Rank。

struct BlackjackCard {
// 嵌套的 Suit 枚举
enum Suit: Character {
// 具体实现...
}
// 嵌套的 Rank 枚举
enum Rank: Int {
// 具体实现...
}
}

那么图示中的 Map 结构体中包含了两个嵌套定义的结构体(Model,Position)和两个嵌套定义的枚举(Direction,Size)

命名空间又是什么

wiki 上关于命名空间的一段定义:

名字空间(英语:Namespace),也称命名空间、名称空间等,它表示着一个标识符(identifier)的可见范围。一个标识符可在多个名字空间中定义,它在不同名字空间中的含义是互不相干的。这样,在一个新的名字空间中可定义任何标识符,它们不会与任何已有的标识符发生冲突,因为已有的定义都处于其他名字空间中。

例如,设Bill是X公司的员工,工号为123,而John是Y公司的员工,工号也是123。由于两人在不同的公司工作,可以使用相同的工号来标识而不会造成混乱,这里每个公司就表示一个独立的名字空间。如果两人在同一家公司工作,其工号就不能相同了,否则在支付工资时便会发生混乱。

那么 Swift 的嵌套类型和命名空间到底又有何联系呢?

以下是一些个人的愚见:

在 Swift 中并没有所谓的 name spacing,但是通过嵌套类型,结合上一个问题中的示例代码,我们可以做到区分 BlackjackCard.SuitNormalCard.Suit ,从这种角度上来说,我们利用了嵌套类型这个特性来生成了一个命名空间并很好区分了不同 card 里面的 Suit 类型。

[ Position: Terrain.Model ] 这段代码是啥意思

这是声明了 terrain 变量是一个字典类型,它的 key 是 Position 类型,它的 value 是 Terrain.Model 类型

字典类型的简化语法有 2 种,一种是 Dictionary<Key, Value> ,一种就是 [Key: Value]

为什么 Position 没有遵守 Hashable 就能做 Dictionary 的 key

Dictionary 里的 key 遵守 Hashable 这个规定没变,图片里的代码应该是一段不完整的示例代码,在 Dictionary 里面的 key 必须遵守 Hashable 协议,4.1 之前需要手动的返回 hashValue ,而在 4.1 之后只需要遵守 Hashable 协议后,编译器会自动帮我们完成 hashValue 的生成。

为什么 Swift 的枚举值可以是字符串

这就是 Swift 的厉害之处了,在 Swift 中枚举是一等类型,它可以采用许多原先只被类所支持的特性,详情可以参考 枚举 里的内容