泛型(三)

Arrays

虽然原来的Keeper类型说明了泛型类型不需要存储任何内容或使用它的类型参数,但泛型类型的最常见就是同时具有这两种功能。这就是Array类型。

使用泛型数组是发明泛型类型的原始动机的一部分。由于许多程序需要相同类型的数组,所以泛型数组使代码更安全。

你一直在使用数组,但是只有[Element]的预防,而不是Array<Element>. 思考一个这样的数组:

let animalAges: [Int] = [2,5,7,9]

这相当于下面这个数组:

let animalAges: Array<Int> = [2,5,7,9]

Array<Int>和[Int]是完全可互换的。你甚至可以通过[Int]()而不是Array <Int>()来调用数组的默认初始化方法。

由于Swift数组只允许对元素序列进行索引访问,所以它们对元素类型没有要求。但情况并非总是如此。

Dictionaries

Swift泛型允许多个类型参数和对它们的一系列复杂的限制。它们允许你使用具有关联类型的泛型类型和协议来建立复杂的算法和数据结构。字典就是一个简单的例子。

Dictionary在逗号分隔的泛型参数列表中有两个类型参数,它们位于尖括号之间,您可以在它的声明中看到:

struct Dictionary<Key: Hashable, Value> // etc..

Key和Value表示字典的键和值的类型。但是Key上的注释,Key: Hashable表示的意义很多。冒号之后的所有内容都是类型约束。类型约束指明了该类型参数父类型,以及所需的协议或协议列表。

例如,Dictionary的类型约束要求作为Dictionary键的任何类型都是hashable,因为Dictionary是一个散列映射,必须对其键进行散列,以启用快速查找。

要实例化具有多个类型参数的类型(如Dictionary),只需提供一个逗号分隔的类型参数列表:

let intNames: Dictionary<Int, String> = [42: "forty-two"]

与数组一样,字典在Swift中也有一些特殊的处理,因为它们是内置的,而且非常常见。你已经见过速记表示法[Key: Value],还可以使用类型推断:

let intNames2: [Int: String] = [42: "forty-two", 7: "seven"]
let intNames3 = [42: "forty-two", 7: "seven"]

Optionals

最后,对泛型的讨论如果不提及Optionals,就不完整。Optionals通过枚举实现,但它们也是另一种泛型类型,你可以自己定义它。

假设你正在编写一个应用程序,该应用程序允许用户以表单的形式输入她的生日,但不是必须的。你可能会发现定义enum类型很方便,如下所示:

enum OptionalDate {
  case none
  case some(Date)
}

类似地,如果另一个表单不要求用户输入她的姓,你可以定义以下类型:

enum OptionalString {
  case none
  case some(String)
}

然后,你可以捕获用户所输入或未输入的所有信息:

struct FormResults {
  // other properties here
  var birthday: OptionalDate
  var lastName: OptionalString
}

如果你发现新类型在重复做这些,那么你会想把它归纳成一个泛型类型来表示“可能存在的特定类型的值”的概念。因此,你可以这样写:

enum Optional<Wrapped> {
  case none
  case some(Wrapped)
}

此时,你将复制Swift自己的Optional < Wrapped >类型,因为这与Swift标准库中的定义非常接近!事实证明,Optional < Wrapped >接近于一个普通的旧泛型类型,就像你自己编写的类型一样。

只有当你与Optional进行交互时,它才会是一个泛型类型,比如:

var birthdate: Optional<Date> = .none
if birthdate == .none {
  // no birthdate
}

但是,当然,下面这样的更常见也更传统:

var birthdate: Date? = nil
if birthdate == nil {
  // no birthdate
}

实际上,这两个代码块的含义完全相同。

与数组和字典一样,optionals在语言中具有这种语法的特权地位,使使用它们更简洁。但是所有这些特性都提供了访问底层类型的更方便的方法,这只是一个普通的枚举类型。

泛型函数参数

到目前为止,你已经了解了泛型类型在函数、类、结构和枚举中的定义。除了Dictionary之外,所有这些都有一个通用参数。

泛型类型参数列表位于类型名或函数名之后。然后可以在定义的其余部分中使用泛型参数。

这个函数接受两个参数并交换它们的顺序:

func swapped<T, U>(_ x: T, _ y: U) -> (U, T) {
  return (y, x)
}
swapped(33, "Jay")  // returns ("Jay", 33)

泛型函数定义展示了语法的一个令人困惑的方面:它同时具有类型参数和函数参数。您拥有类型参数<T、U>的通用参数列表和函数参数列表(_ x: T、_ y: U)。

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

推荐阅读更多精彩内容