[Swift]学习笔记-可选类型/可选链

可选类型/可选链                        Make-by-LJW ---转载请注明出处...

  • 它的可选性体现于请求或调用的目标当前可能为空(nil)

    • 如果可选的目标有值,那么调用就会成功;
    • 如果选择的目标为空(nil),则这种调用将返回空(nil)
  • 多次调用被链接在一起形成一个链,如果任何一个节点为空(nil)将导致整个链失效。
  • 因为可选链的结果可能为nil,可能有值.因此它的返回值是一个可选类型.

    • 可以通过判断返回是否有值来判断是否调用成功
    • 有值,说明调用成功
    • 为nil,说明调用失败

取值:

// 从可选链中取值:?. --> 取出的值为可选类型
// 在可选链中取值的过程中,编译器会自动判断每一个可选类型是否有值,如果可选类型有值,那么系统会对该可选类型进行解包. 如果发现可选类型没有值,那么系统会自动返回nil

let price = p.dog?.toy?.price

 

赋值

给可选链赋值
    1.判断所有的可选类型是否有值,如果都没有值,则该语句相当于没有执行
    2.如果所有的可选类型都有值,则系统会自动给可选类型进行解包,解包之后,在进行赋值

p.dog?.toy?.price = 50

调用可选链中的方法

if let whyDog = p.dog {
    if let toy = whyDog.toy {
        toy.flying()
    }
}

// p.dog!.toy!.flying()
直接写法:
p.dog?.toy?.flying()

可选类型

可选类型的本质其实就是一个枚举

None 没有值
Some 有值

格式: Optional<类型>  或 在类型后面加上?号

由于可选类型在Swift中随处可见, 所以系统做了一个语法糖, 在类型后面加上?

var opa: Optional<Int>
var opb: Int?
var nora: Int
nora = 10

print(nora)
print(opb)

输出结果:
10
nil

基本类型变量, 在使用之前必须进行初始化, 否则报错

目的: 安全, 不管在什么时候访问都是有意义的

普通变量和可选类型的区别, 普通变量只有一种状态, 有值

注意:Swift的变量和C/OC的不一样, C/OC可以没有值, 是一个随机值

可选类型是安全的么? 是, 可以通过可选绑定判断后再使用

Swift的发明者完全是基于安全的考虑, 当我们使用基本类型时完全不用考虑是否有值

当我们使用可选类型时, 总会记得先判断再使用. 让程序时刻了解哪些有值哪有没有值

var opb: Int?
opb = 55
if let b = opb{
    print(opb!)
    print(b)
}
输出结果:
55
55

 

可选链

通过可选类型的变量来调用相应的属性和方法

可选链的返回值是一个可选值
格式:
可选值?.属性

可选值?.方法

class Person {
    var name: String
    init(name:String){
        self.name = name
    }
    func whoami() ->String{
        print("my name is \(self.name)")
        return name
    }
}
var p0 : Person?
var p1 : Person = Person(name: "ljw")
p1.name = "zs"
p1.whoami()
输出结果:
my name is zs

如何通过可选类型来调用对应的方法和属性

1.通过强制解包

但是强制解包非常危险, 如果可选类型没有值, 会引发运行时错误

    p0!.name = "ls"
   p0!.whoami()

2.通过可选绑定, 代码繁琐

if let p = p0{
    p.name = "ls"
    p.whoami()
}

3.通过可选链, 如果问号前面的变量没有值, 整个可选链会失效

p0 = p1
p0?.name = "ls"
p0?.whoami()

可选链的返回值会自动包装成一个可选值

因为可选链可用能失效

所以返回值可能有值也可能没有值

要想表达有值或者没有值只能用可选值, 所以返回值会自动包装成一个可选值

print(p0?.name)
print(p0?.whoami())
print(p1.name)
var a:String? = p0?.name
p0?.name = "ww"
var b:String = p1.name
输出结果:
nil
nil
xmg

 

可选链调用下标索引
格式:

可选值?[]

struct Student {
    var name:String = "ljw"
    var math:Double = 99.0
    var chinese:Double = 99.0
    var english:Double = 99.0

要想实现下标访问, 必须实现subscript方法

如果想要通过下标访问, 必须实现get方法

如果想要通过下表赋值, 必须实现set方法

subscript(course:String) ->Double?{
        get{
            switch course{
            case "math":
                return math
            case "chinese":
                return chinese
            case "english":
                return english
            default:
                return nil
            }
        }
        set{
            switch course{
            case "math":
                因为返回的是可选类型
                math = newValue!
            case "chinese":
                chinese = newValue!
            case "english":
                english = newValue!
            default:
                print("not found")
            }

        }
    }
}
var stu:Student? = Student()
可选链调用下标索引不需要., 直接在问号后面写上[]即可
print(stu?["math"])
输出结果:Optional(99.0)

 

利用可选链赋值. 注意: 早起版本中不能利用可选链赋值

stu?.name = "ww"
print(stu?.name)
输出结果:Optional("ww")

利用可选链给下标赋值

stu?["math"] = 88
print(stu?["math"])
输出结果:Optional(88.0)

 

判断赋值操作是否成功, 可选链的赋值操作也有返回值

如果赋值成功会返回一个可选类型

返回()?也就是Viod? 代表成功.

返回nil代表失败

let res: Void? = stu?.name = "ljw"
print(res)
输出结果:Optional(()) 代表成功.
stu = nil
let res: Void? = stu?.name = "zl"
print(res)
输出结果:nil 代表失败

多层可选链:
单层:可选值?.属性
多层:可选值?.属性.属性?.属性 或者 可选值?.属性?.属性?.属性

class A {
    var name:String = "ljw"
}
class B{
    var a1:A?
}
class C{
    var b1:B = B()
}
class D{
    var c1: C?
}

var a1 = A()
var b1 = B()
var c1 = C()
var d1 = D()

d1.c1 = c1
通过d直接给b赋值
由于D中的C是可选值, 所以需要在C后面加上?
d1.c1?.b1.a1 = a1
通过d直接获取a中的name
其实只需要在可选值后面加上问号即可, 如果可选值不存在, 那么后面的链失效
print(d1.c1?.b1.a1?.name)
输出结果:Optional("ljw")

 

 

 

 

 

时间: 2024-10-21 21:28:02

[Swift]学习笔记-可选类型/可选链的相关文章

Swift学习笔记 - 可选 ?

可选类型 使用可选类型(optionals)来处理值可能缺失的情况.可选类型表示: 有值,等于 x 或者 没有值 注意:C 和 Objective-C 中并没有可选类型这个概念.最接近的是 Objective-C 中的一个特性,一个方法要不返回一个对象要不返回nil,nil表示“缺少一个合法的对象”.然而,这只对对象起作用——对于结构体,基本的 C 类型或者枚举类型不起作用.对于这些类型,Objective-C 方法一般会返回一个特殊值(比如NSNotFound)来暗示值缺失.这种方法假设方法的

swift学习第九天:可选类型以及应用场景

可选类型的介绍 注意: 可选类型时swift中较理解的一个知识点 暂时先了解,多利用Xcode的提示来使用 随着学习的深入,慢慢理解其中的原理和好处 概念: 在OC开发中,如果一个变量暂停不使用,可以赋值为0(基本属性类型)或者赋值为空(对象类型) 在swift开发中,nil也是一个特殊的类型.因为和真实的类型不匹配是不能赋值的(swift是强类型语言) 但是开发中赋值nil,在所难免.因此推出了可选类型 可选类型的取值: 空值 有值 定义可选类型 定义一个可选类型有两种写法 最基本的写法 语法

Swift学习笔记(二)参数类型

关于参数类型,在以前的编程过程中,很多时间都忽视了形参与实参的区别.通过这两天的学习,算是捡回了漏掉的知识. 在swift中,参数有形参和实参之分,形参即只能在函数内部调用的参数,默认是不能修改的,如果想要修改就需要在参数前添加var声明. 但这样的声明过后,仍旧不会改变实参的值,这样就要用到inout了,传递给inout的参数类型必须是var类型的,不能是let类型或者字面类型,(字面类型是在swift中常提的一个术语,个人认为就是赋值语句,也不能修改)而且在传递过程中,要用传值符号"&

SWIFT学习笔记02

1.//下面的这些浮点字面量都等于十进制的12.1875: let decimalDouble = 12.1875 let exponentDouble = 1.21875e1 let hexadecimalDouble = 0xC.3p0//==12+3*(1/16) 2.//类型别名,用typealias关键字来定义类型别名 typealias AudioSample = UInt16 var maxAmplitudeFound = AudioSample.min 3.//元组 let ht

Swift学习笔记十:属性

1.存储属性       1. 作为特定类或结构实例的一部分,存储属性存储着常量或者变量的值.存储属性可分为变量存储属性(关键字var描述)和常量存储属性(关键字let描述). struct student{ let name = "" var score = 0 } let a = student(name:"小笨狼",score:96)           注意:                ① 定义储存属性时,需要为每一个属性定义一个默认值.在初始化的时候,

swift学习笔记(七)自动引用计数

与Object-c一样,swift使用自动引用计数来跟踪并管理应用使用的内存.当实例不再被使用时,及retainCount=0时,会自动释放是理所占用的内存空间. 注:引用计数仅适用于类的实例,因为struct和enumeration属于值类型,也就不牵涉引用,所以其存储和管理方式并不是引用计数. 当一个实例被初始化时,系统会自动分配一定的内存空间,用于管理属性和方法.当实例对象不再被使用时,其内存空间被收回. swift中的引用类型分为三种,即Strong强引用,weak弱引用和无主引用unw

Swift学习笔记(三):Protocols and Delegates

一.协议 | Protocols 协议用于定义完成某些功能所需要的方法和属性,协议本身并不提供这些功能的具体实现,只是用来描述这些实现.类.结构体.枚举通过提供协议所要求的方法.属性的具体实现来采用协议.能够满足协议要求的类型称之为协议的遵循者. 协议可以要求遵循者提供特定的实例属性.实例方法.类方法.操作符或下标脚本等. //创建一个协议,协议说声明了一个方法Speak protocol Speaker { func Speak() } //类Vicki遵循Speaker协议,在类中具体实现了

Swift学习笔记(13)--属性 (Properties)

普通属性用var和let即可,本文不做详述 1.延迟存储属性 延迟存储属性是指当第一次被调用的时候才会计算其初始值的属性.在属性声明前使用@lazy来标示一个延迟存储属性. class DataImporter { /* DataImporter 是一个将外部文件中的数据导入的类. 这个类的初始化会消耗不少时间. */ var fileName = "data.txt" // 这是提供数据导入功能 } class DataManager { @lazy var importer = D

Swift学习笔记(11)--类与结构体

类与结构是编程人员在代码中会经常用到的代码块.在类与结构中可以像定义常量,变量和函数一样,定义相关的属性和方法以此来实现各种功能. 和其它的编程语言不太相同的是,Swift不需要单独创建接口或者实现文件来使用类或者结构.Swift中的类或者结构可以在单文件中直接定义,一旦定义完成后,就能够被直接其它代码使用. 注意:一个类的实例一般被视作一个对象,但是在Swift中,类与结构更像是一个函数方法,在后续的章节中更多地是讲述类和结构的功能性. 1.类和结构的异同 类和结构有一些相似的地方,它们都可以