iOS Swift5 构造函数分析(二):init 构造函数在struct与class中的区别

一、前言

上篇《关键字 designated、convenience、required》中,我们了解到了 swift 在构造器这块给我们带来的新特性,结合我们之前的一篇《浅析结构体(struct)与类(class) 》,我们今天就来聊聊在 struct 与 class 中的应用与不同。

二、默认构造器

先来个灵魂拷问:何谓『默认构造器』?
不显式定义给出构造器(构造函数),由系统自动添加生成!(在 Swift 中,默认构造器就是 designated 构造器)

是不是光看文字理解有点困难?那我就来个 demo 演示。

2.1、struct

struct DemoStruct {
    var name: String
    var age: Int
}

没有构造方法(init),但我们可以这么来初始化使用:

struct-before.png

当我们输入『左括号』时,Xcode 自动提示,给了我们一个唯一的初始化方法,这个就是『默认构造器』,我们也可以显式这样来创建:

struct-init.png

即通过 init 构造器来初始化,但同样,Xcode 也提示我们有两个参数。为啥是有参数,而不是无参,例如:DemoStruct.init() ?

2.1.1、逐一成员构造器

这是 Swift 规范:当我们没有显式指定至少一个 init 构造器时,swift 会为我们添加一个默认构造器,该构造器的入参即是 struct 中的所有成员!

上面例子中,我们定义了两个成员,分别是:name 和 age,因此,swift 会按照从上到下,依次将其纳入到默认构造器中,即创建了如下构造器:

swift-struct.png

如果 struct 讲到这里就完了,是不是很没意思?如果你认为这就完了,你就『Too Young Too Simple』了!

如果我们的 struct 中有很多成员变量,虽然 swift 会为我们创建默认构造器,但是,我们在使用时,每个参数都需要传入,使用就会很麻烦,那有没有其它方式呢?例如,初始化时,我只想传 name :

optional.png

上面的代码片段没有报错,运行无任何问题!

我们有三种解决方式:

  • 可选参数默认构造器;
  • 默认参数默认构造器;
  • 扩展构造器;

2.1.2、可选参数默认构造器

param-nil.png

我们看到,age 的类型是 Int? ,但可为 nil;因此,我们可以在初始化时,只需要传入强制必要的参数:

struct-param-nil.png

2.1.3、默认参数默认构造器

名字有点绕,但效果很简单:

param-def.png

2.1.4、扩展构造器

扩展,即 extension ,swift 提供的一种方式,无论是 struct 还是 class 都可以使用:

// 扩展 struct
extension DemoStruct {
    // 重载一个构造器
    // 该构造器调用默认构造器
    init(name: String) {
        self.init(name: name, age: 18)
    }
}

执行结果如下:

struct-result.png

2.2、class

同样,先来定义一个 class,代码如下:

class DemoClass {
    var name: String
    var age: Int
}

如果仅是这样,Xcode 会立即提示报错(类没有构造器):

no-init.png

我们至少需要显式指定(explicit designated)一个构造器,对于 DemoClass,我们要按照类似 struct 的逐一成员构造器那样,定义一个构造器,如果只构造部分成员的构造器,则会如下报错:

not-all-init.png

该错误提示:没有初始化所有的成员。对于这种情况,我们有三种方式来完成:

  • 将 age 设置为可默认为 nil 类型(等同于 2.1.2);
  • 定义 age 时就给定默认值(等同于 2.1.3);
  • 在构造器中给定默认值(如下代码所示);
class DemoClass {
    var name: String
    var age: Int
    
    init(name: String) {
        self.name = name
        // 构造器中给定默认值
        self.age = -1
    }
}

class 要求必需显式指定一个构造器,而 struct 则是由 swift 自动添加。同样,class 也可以通过扩展(extension)来重载构造器(注:扩展类的构造器,是需要便利的,即添加关键字:convenience):

extension DemoClass {
    convenience init(name: String, age: Int) {
        self.init(name: name)
        self.age = age
    }
}

我们执行看下结果:

class-result.png

三、可失败构造器

类似 Kotlin 都有一种类型叫可null类型,Swift 也不甘落后,也有可空类型,而且 Swift 更进一步,允许在创建变量(struct)、对象(class)或枚举时,返回空对象(即创建失败,返回为 nil )。

\color{red}{注意:根据官方文档,明确说了目前只有 struct、class、enum 可以在创建时返回 nil !}

  • 什么叫空类型?
// T 代表任何类型
// variable 代表变量、对象
var variable: T? = nill

// 例如:
var str: String? = nil // 可 nil 字符串
var num: Int? = nil    // 可 nil 整型
  • 如何定义可失败构造器?

可失败构造器定义非常简单,只需要在 init 后加个问号,即:init? 即可,例如下图:

define-init-nil.png

我们可以看到,我们定义了一个可失败构造器,如果创建 Person 时,传入的字符串是『空字符串』,那么我们就返回 nil,否则就成功创建。从上图中,我们还能发现,可失败构造器的返回类型是:T?,在上面的例子中,返回类型是 Person?,即代表可能为 nil 。

dif-use-init-nil.png

上图是我们的测试代码,执行后打印结果非常清楚。对于 class 或者 enum ,与 struct 类似,我就不再演示,大家可自行测试。

四、个人感想

可人有些朋友要问:为何要花如此大的力气来分析 struct 和 class ?难道就是因为 Swift 新增了 struct 所以才写这些么?

不,因为我在做《iOS Swift5从0到1系列》中,发现每当我实现一些功能时,就会或多或少涉及到一些 Swift 的新特性,虽然这些特性在 Swift 一出来就有,但是,我不确定大家都非常的了解熟悉,因此,但凡涉及到 Swift 中新的知识点,我都会单独开一些分支系列来提前讲解分析,希望大家能够一点一点的学习与吸收,而不是我一下子抛出很多新的知识点,导致大家难以消化吸收,影响心情放中途放弃。

Swift 其实非常简单,我希望让大家和我一起共同成长进步,还可以快乐的交流,并且,本着我的博客中,所有的文章都是高质量,且可吸收(无论是 iOS 还是 Java、Android 或者 H5),因此,我会在讲解主线的同时,穿插不同支线;同时,一篇高质量的博文也要好几天(哪怕是分支内容),因此,希望大家不要心急。

谢谢!

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

推荐阅读更多精彩内容