跳到主要内容

Swift中的初始化器

提示
  1. 初始化器的定义和用途:Swift 中的初始化器 (init()) 是一种特殊的函数,用于创建类或结构体的实例,并初始化其属性。
  2. 带参数和可失败的初始化器:初始化器可以带参数,用于自定义实例创建过程;可失败的初始化器 (init?()) 在条件不满足时返回 nil
  3. 构造器重载和逐成员初始化器:Swift 支持构造器重载,允许同一类中有不同参数的多个初始化器;结构体自动获得逐成员初始化器,简化实例创建。

初始化器是一种特殊的函数,用于创建类或结构体的对象。

在 Swift 中,我们使用 init() 方法来创建初始化器。例如,

class Wall {
...

// 创建一个初始化器
init() {
// 执行初始化操作
...
}
}

这里,方法 init() 是类 Wall 的一个初始化器。

示例:Swift 初始化器

// 声明一个类
class Wall {
var length: Double

// 初始化器用于初始化属性
init() {
length = 5.5
print("创建一面墙。")
print("长度 = ", length)
}
}

// 创建一个对象
var wall1 = Wall()

输出

创建一面墙。
长度 = 5.5

在上面的例子中,我们创建了一个名为 init() 的初始化器。在初始化器内部,我们初始化了 length 属性的值。

注意以下语句:

// 创建一个对象
var wall1 = Wall()

这里,当创建 wall1 对象时,调用了 init() 初始化器。并且 length 属性的值被初始化为 5.5

带参数的初始化器

Swift 初始化器也可以接受一个或多个参数。这样的初始化器被称为带参数的初始化器(带参数的初始化器)。

让我们看一个例子,

class Wall {

var length: Double
...

// 带参数的初始化器
init(length: Double) {

self.length = length
}
}

// 创建一个对象
var wall1 = Wall(length: 10.5)

这里,

  • init(length: Double) - 带参数 length 的初始化器
  • var wall1 = Wall(length: 10.5) - 将值 10.5 传递给参数 length
  • self.length = length - 将 length 参数的值(10.5)分配给 length 属性
  • self.length - 指定 length 属性与当前对象 wall1 关联

示例:带参数的初始化器

// 声明一个类
class Wall {
var length: Double
var height: Double

// 带参数的初始化器用于初始化属性
init(length: Double, height: Double) {
self.length = length
self.height = height
}

func calculateArea() -> Double {
return length * height
}
}

// 创建对象并初始化数据成员
var wall1 = Wall(length: 10.5, height: 8.6)
var wall2 = Wall(length: 8.5, height: 6.3)

print("Wall 1 的面积: ", wall1.calculateArea())
print("Wall 2 的面积: ", wall2.calculateArea())

输出

Wall 1 的面积:  90.3
Wall 2 的面积: 53.55

在上面的例子中,我们创建了一个带有两个参数的初始化器 init()lengthheight。注意表达式,

var wall1 = Wall(length: 10.5, height: 8.6) var wall2 = Wall(length: 8.5, height: 6.3)

在这里,我们创建 Wall 类的对象时,将成员属性的值作为参数传递。

成员变量初始化后,我们现在可以使用 calculateArea() 方法来计算墙的面积。

构造器重载

Swift 中的构造器可以像 函数重载 那样重载。

在构造器重载中,如果两个或更多构造器的参数类型或数量不同,它们可以有相同的名称。

基于在创建对象时传递的参数,将调用相应的构造器。

让我们看一个例子,

class Person {
var age: Int

// 1. 无参数的构造器
init() {
age = 20
}

// 2. 带有参数的构造器
init(age: Int) {
self.age = age
}

// 返回年龄的方法
func getAge() -> Int {
return age
}
}

var person1 = Person()
var person2 = Person(age: 23)

print("Person1 年龄:", person1.getAge())
print("Person1 年龄:", person2.getAge())

输出

Person1 年龄: 20
Person1 年龄: 23

在上面的例子中,我们创建了一个名为 Person 的类,它有一个属性 age

我们还定义了两个构造器:init()init(age: Int)

  1. 我们没有向 person1 对象传递任何参数,所以调用了第一个构造器。因此,age 被初始化为 20
  2. 我们向 person2 传递了 23 作为参数。因此,调用了第二个构造器,age 被初始化为 23

getAge() 方法返回 age 的值,我们使用它来打印 person1person2 的年龄。

Swift 方便的构造器

在前面的例子中,我们定义的构造器是类的主要构造器。这些主要构造器也称为 指定构造器

然而,我们也可以为类定义一个次级/支持性的构造器,称为 方便构造器

要定义方便构造器,我们在构造器前使用 convenience 关键字。例如,

class University {

var name : String
var rank : String

init(name : String, rank: String) {
self.name = name
self.rank = rank
}

// 定义方便构造器
convenience init() {
self.init(name: "Kathmandu University", rank: "1st")
}

}

var university1 = University()
print(university1.name)
print("排名:", university1.rank)

输出

Kathmandu University
排名: 1st

在上面的例子中,我们创建了一个指定构造器:init() 和一个方便构造器:convenience init()

在方便构造器内部,我们调用了指定构造器并为属性赋值。

convenience init() {
self.init(name: "Kathmandu University", rank: "1st")
}

university1 对象被创建时,将调用方便构造器。

// 使用方便构造器
var university1 = University()

与调用指定构造器相比,这使我们的代码看起来更加清晰:

// 调用指定的初始化器
var university1 = University(name: "Kathmandu University", rank: "1st")

注意:在为存储属性分配默认值时,便利初始化器非常有用。

可失败初始化器

在某些情况下,初始化器可能成功或失败,这就是所谓的可失败初始化器。

我们通过在 init 关键字后加一个问号 (?) 来编写一个可失败的初始化器,并在出现问题时返回 nil。例如,

class File {

var folder: String

// 可失败初始化器
init?(folder: String) {

// 检查是否为空
if folder.isEmpty {
print("未找到文件夹") // 第一条输出
return nil
}
self.folder = folder
}
}

// 创建 folder1 对象
var file = File(folder: "")
if (file != nil) {
print("成功找到文件")
}
else {
print("查找文件时出错") // 第二条输出
}

输出

未找到文件夹
查找文件时出错

在上面的例子中,我们创建了一个带有参数 folder 的可失败初始化器 init?()

并且,我们使用了 if 语句和 isEmpty 属性

if (folder.isEmpty) { return nil }

来检查 folder 是否为空,并在它为空时返回 nil

对于 folder1 对象,我们传递了一个空字符串 "",这触发了初始化失败,因此首先执行了其中的语句,然后返回了 nil

最后,执行了 else 块中的语句

结构体的逐成员初始化器

在 Swift 中,处理结构体时我们不需要创建初始化器。Swift 会为我们自动生成一个逐成员的初始化器。例如,

struct Person {

var name: String
var age: Int
}

这里,我们在 Person 结构体内没有创建任何初始化器。然而,Swift 为我们自动生成了一个逐成员的初始化器,

var person1 = Person(name: "Dwight", age: 43)

这里,括号 () 内的值会自动赋给结构体的相应属性。这就是所谓的逐成员初始化器。

示例:逐成员初始化器

struct Person {

// 定义两个属性
var name: String
var age: Int
}

// 使用逐成员初始化器创建 Person 对象
var person1 = Person(name: "Dwight", age: 43)

print("姓名:", person1.name)
print("年龄:", person1.age)

输出

姓名: Dwight
年龄: 43

在上面的例子中,我们使用了自动生成的逐成员初始化器为 Person 结构体的相应属性赋值。

var person1 = Person(name: "Dwight", age: 43)

这里,name 的值被设置为 Dwightage 被设置为 43