Swift:可选类型(optional)与构造函数

来源:互联网 发布:qq赚钱软件 编辑:程序博客网 时间:2024/05/18 01:21

可选类型与构造函数

导语

在swift快速入门时,发现自己很难理解可选类型
所以本文通过一些类的互相调用来加强对可选类型的理解
本文涉及的内容有 类,构造函数,可选类型的定义和使用

基本知识

1. 定义及初始化

可选类型是swift中特有的,c和objective-c中都没有这个概念。
当你定义一个类型为可选类型时,它可以为nil,或者可以一个值

//申明一个可选型字符串,未初始化默认为nilvar optionStr: String?//申明一个可选性Int常量,无初始化let num: Int?

我们做个实验,令num = 1,再num = 2,结果如下图。

我们可以看到,在第一次 num = 1,其实是对num进行初始化,所以并不会报错。
而当第二次赋值时,则系统提示错误,说常量num只能初始化一次。

总结
如果申明的是var 可选型变量,则初始化的值为nil
如果申明的是let 可选型常量,则第一次赋值操作为初始化,并不会自动初始化为nil

2. 强制类型转换时的option

强制类型转换时,如Int()操作,不是所有的String都可以转换为Int,所以在这时候就体现的可选型的作用,要么返回Int,要么返回nil

//converedNumber和converedNum被推测为类型"Int?"let possibleNumber = "123"let convertedNumber = Int(possibleNumber)let possibleNum = "hello"let convertedNum = Int(possibleNum)

深入探讨

1.初始化和可选型的关系

先定义一个Room类

class Room {    let name: String    //init中可以初始化name的值    init(name: String) {self.name = name}}

我们尝试一下一些错误的定义:
1. 如果在类中申明实例变量,则必须有构造函数或者在申明变量时对其进行初始化,而可选型的变量是可以不初始化的,因为系统会将其初始化为nil
2. 如果在类中申明常量,则不管是否是可选型,都必须初始化,因为常量是没有办法修改其值的,所以必须初始化

2.type! 和type? 的区别

再定义一个Residence类,Person类

class Person {    //此处residence为可选型,初始值为nil    var residence: Residence?}class Residence {    var rooms = [Room]()    var numberOfRooms: Int {        return rooms.count    }    subscript(i: Int) -> Room {        get {            return rooms[i]        }        set(newValue) {            rooms[i] = newValue        }    }    func printNumberOfRooms() {        print("The number of rooms is \(numberOfRooms)")    }}

然后申请一个Person实例john, 当调用实例方法时出错


原因在于,我们在Person中申明的是Residence?类,此处调用时

//要么使用let roomCount = john.residence?.numberOfRooms//要么使用let roomCount = john.residence!.numberOfRooms

类型type?和类型type!中符号的意思
?: 告诉编译器我不确定这个变量是否有值,有值就继续调用,否则返回nil
!: 告诉编译器这个变量是肯定有值的,否则报错

我们再尝试一下别的错误

这里的原因是我们Person类中申明Residence?时没有初始化,所以默认初始化为nil,而此处用!来解析绑定,就会导致错误
我们可以在Person类中对residence进行初始化

class Person {    //有两种初始方式,我推荐用构造器初始化    var residence: Residence? = Residence()//    init() {//        residence = Residence()//    }}

由于初始化后,residence的值不再为空,则调用john.residence!就不会出错

举例说明(iOS)

此问题来自swift里!号的意义
楼主的的问题是不明白为什么有时候用!,有时候用?

var amiteLbl: UILabel?self.amiteLbl = UILable(frame:CGRectMake(50, 100, 200, 40))self.amiteLbl!.text = "I love mixbox"self.view?.addSubview(self.amiteLbl)

我们分析一下
1.首先我们定义一个UILable?,然后对其进行初始化
2.此时self.amiteLbl!.text的原因是我们对amiteLbl进行了初始化,我们确定其值不为空,所以使用了!
3.而self.view?为什么用的是?呢,因为我们不确定view是否为空,如果此时贸然使用!,当view为nil时,程序就会崩溃。
4.我们也可以翻译一下self.view?.addSubview(self.amiteLbl)

if let theView = self.view {    theView.addSubview(self.amiteLbl)} else {    return nil}

参考:
苹果官方文档

0 0
原创粉丝点击