Swift基础语法 - 可选项

news/2024/7/20 22:28:44 标签: swift, ios, 开发语言

可选项(Optional)

  • 可选项,一般也叫可选类型,它允许将值设置为 nil
  • 在类型名称后面加个问号 ? 来定义一个可选项
swift">var name: String? = "CSDN"
name = nil

var age: Int? //默认就是nil
age = 30
age = nil

在这里插入图片描述

swift">var array = [2, 4, 6, 8]

func getNumber(_ index: Int) -> Int? {
    if index < 0 || index >= array.count {
        return nil
    }
    return array[index]
}

print(getNumber(1)) //Optional(4)
print(getNumber(-1)) //nil
print(getNumber(4)) //nil

在这里插入图片描述

强制解包(Forced Unwrapping)

  • 可选项是对其他类型的一层包装,可以将它理解为一个盒子
  • 如果为 nil ,那么它是个空盒子
  • 如果不为 nil ,那么盒子里装的是:被包装类型的数据
swift">var age: Int? //默认就是nil
age = 10
age = nil

在这里插入图片描述

  • 如果要从可选项中取出被包装的数据(将盒子里装的东西取出来),需要使用 感叹号 ! 进行强制解包
swift">var age: Int? = 20

let ageInt: Int = age!

print(ageInt) //20

在这里插入图片描述

  • 如果对值为 nil 的可选项(空盒子)进行强制解包,将会产生运行时错误
swift">var age: Int?
age!

在这里插入图片描述

Fatal error: Unexpectedly found nil while unwrapping an Optional value

判断可选项是否包含值

swift">let number = Int("123")

if number != nil {
    print("字符串转成数字成功为:\(number!)")
}else{
    print("字符串转成数字失败")
}
// 字符串转成数字成功为:123

可选项绑定(Optional Binding)

  • 可以使用 可选绑定 来判断可选项是否包含值
  • 如果包含就自动解包,把赋值给一个临时的常量( let )或者变量( var ),并返回 true ,否则返回 false
swift">if let number = Int("123") {
    print("字符串转成数字成功为:\(number)")
    // number 是强制解包之后的Int值
    // number 作用域仅限于这个大括号
}else{
    print("字符串转成数字失败")
}
// 字符串转成数字成功为:123
swift">enum Season : Int {
    case spring = 1, summer, autumn, winter
}

if let season = Season(rawValue: 8){
    switch season {
    case .spring:
        print("the season is spring")
    default:
        print("the season is other")
    }
} else {
    print("no such season")
}
// no such season

等价写法

swift">if let first = Int("5") {
    if let second = Int("45") {
        if first < second && second < 50 {
            print("\(first) < \(second) < 50")
        }
    }
}
// 5 < 45 < 50

if let first = Int("5"),
   let second = Int("45"),
   first < second && second < 50 {
    print("\(first) < \(second) < 50")
}
// 5 < 45 < 50

while 循环中使用可选项绑定

swift">//遍历数组,将遇到 的正整数都加起来,如果遇到负数或者非数字,则停止遍历
var array = ["10", "20", "30", "ab", "-20", "40"]

var index = 0
var sum = 0
while let num = Int(array[index]), num > 0 {
    sum += num
    index += 1
}
print(sum)

空合并运算符 ?? (Nil - Coalescing Operator)

swift">public func ?? <T>(optional: T?, defaultValue: @autoclosure () throws -> T?) rethrows -> T?
swift">public func ?? <T>(optional: T?, defaultValue: @autoclosure () throws -> T) rethrows -> T
  • a ?? b
  • a 是可选项
  • b 是可选项 或者 不是可选项
  • ba 的存储类型必须相同
  • 如果 a 不为 nil ,就返回 a
  • 如果 a nil ,就返回 b
  • 如果 b 不是可选项,返回 a 时会自动解包
swift">let a: Int? = 1
let b: Int? = 2
let c = a ?? b // c是Int? , Optional(1)
swift">let a: Int? = nil
let b: Int? = 2
let c = a ?? b // c是Int? , Optional(2)
swift">let a: Int? = nil
let b: Int? = nil
let c = a ?? b // c是Int? , nil
swift">let a: Int? = 1
let b: Int = 2
let c = a ?? b // c是Int , 1
swift">let a: Int? = nil
let b: Int = 2
let c = a ?? b // c是Int , 2
swift">let a: Int? = nil
let b: Int = 2
//如果不使用 ?? 运算符
let c: Int
if let tmp = a {
    c = tmp
} else {
    c = b
}

多个 ?? 一起使用

swift">let a: Int? = 1
let b: Int? = 2
let c = a ?? b ?? 3 // c是Int , 1
swift">let a: Int? = nil
let b: Int? = 2
let c = a ?? b ?? 3 // c是Int , 2
swift">let a: Int? = nil
let b: Int? = nil
let c = a ?? b ?? 3 // c是Int , 3

?? 跟 if let 配合使用

swift">let a: Int? = nil
let b: Int? = 2
if let c = a ?? b {
    print(c)
}
//类似于 if a != nil || b != nil
swift">let a: Int? = nil
let b: Int? = 2
if let c = a , let d = b {
    print(c)
    print(d)
}
// 类似于 if a != nil && b != nil

if 语句实现登录

swift">func login(_ info: [String : String]) {
    let username: String
    if let tmp = info["username"] {
        username = tmp
    } else {
        print("请输入用户名")
        return
    }
    let password: String
    if let tmp = info["password"] {
        password = tmp
    } else {
        print("请输入密码")
        return
    }
    // if username ....
    // if password ....
    print("用户名:\(username)", "密码:\(password)", "登陆ing")
}
login(["username" : "jack", "password" : "123456"]) // 用户名:jack 密码:123456 登陆ing
login(["password" : "123456"]) // 请输入密码
login(["username" : "jack"]) // 请输入用户名

guard 语句

swift">guard 条件 else {
    // do something....
    退出当前作用域
    //return、break、continue、throw error
}
  • guard 语句的条件为 false 时,就会执行大括号里面的代码
  • guard 语句的条件为true时,就会跳过 guard 语句
  • guard 语句特别适合用来“提前退出”
  • 当使用 guard 语句进行可选项绑定时,绑定的常量( let )、变量( var )也能在外层作用域中使用
swift">func login(_ info: [String : String]){
    guard let username = info["username"] else {
        print("请输入用户名")
        return
    }
    guard let password = info["password"] else {
        print("请输入密码")
        return
    }
    // if username ...
    // if password ...
    print("用户名:\(username)","密码:\(password)","登录ing")
}
login(["username" : "jack", "password" : "123456"]) // 用户名:jack 密码:123456 登陆ing
login(["password" : "123456"]) // 请输入密码
login(["username" : "jack"]) // 请输入用户名

隐式解包(Implicitly Unwrapped Optional)

  • 在某些情况下,可选项一旦被设定值之后,就会一直拥有值
  • 在这种情况下,可以去掉检查,也不必每次访问的时候都进行解包,因为它能确定每次访问的时候都有值
  • 可以在类型后面加个感叹号 !定义一个隐式解包的可选项
swift">let num1: Int! = 10
let num2: Int = num1
if num1 != nil {
    print(num1 + 6) // 16
}
if let num3 = num1 {
    print(num3) // 10
}
swift">let num1: Int! = nil
//Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value
let num2: Int = num1

在这里插入图片描述

字符串插值

  • 可选项在字符串插值或直接打印时,编译器会发出警告
swift">var age: Int? = 10
print("My age is \(age)")

在这里插入图片描述

  • 至少有3种方法消除警告
swift">print("My age is \(age!)")
//My age is 10

print("My age is \(String(describing: age))")
//My age is Optional(10)

print("My age is \(age ?? 0)")
//My age is 10

多重可选项

swift">var num1: Int? = 10
var num2: Int?? = num1
var num3: Int?? = 10

print(num2 == num3) // true
  • 可以使用lldb指令 frame variable –R 或者 fr v –R 查看区别
swift">var num1: Int? = nil
var num2: Int?? = num1
var num3: Int?? = nil

print(num2 == num3) // false

(num2 ?? 1) ?? 2 // 2
(num3 ?? 1) ?? 2 // 1

http://www.niftyadmin.cn/n/76054.html

相关文章

欧洲杯案例(数据过滤和排序)

1&#xff1a;找到数据的位置 os.path.join(os.getcwd(),Euro2012_stats) 2&#xff1a;可以作为属性去取,变量&#xff0c;所有要符合变量的命名规则&#xff08;不能有空格等&#xff09; 3&#xff1a;有多少支球队参加了2012年的欧洲杯 维度 import pandas as pd impor…

【数据结构】排序算法

目录 1.理解排序 1.1 排序的概念 1.2 排序的运用场景 1.3 常见的排序算法 2.插入排序算法 2.1 直接插入排序 2.2 希尔排序 3.选择排序算法 3.1 直接选择排序 3.2 堆排序 4.交换排序算法 4.1 冒泡排序 4.2 快速排序 4.2.1 hoare 法 4.2.2 挖坑法 4.2.3 前…

SQL 中的窗口函数

SQL 中的窗口函数&#xff08;Window Functions&#xff09;是一种特殊的函数&#xff0c;它可以在查询结果的某个区间内执行计算&#xff0c;而不仅仅是对单个行进行计算。 以下是一些常用的窗口函数&#xff1a; 1、ROW_NUMBER() ROW_NUMBER() 函数可以给查询结果的每一行…

定时器设计

定时器设计 定时器应用&#xff1a; 游戏的Buff实现&#xff0c;Redis中的过期任务&#xff0c;Linux中的定时任务等等心跳检测&#xff0c;如服务器接收队列满了&#xff0c;tcp客户端会定时探测是否能够发送数据 定时器数据结构选取要求&#xff1a; 需要快速找到到期任务…

NSIS脚本

目录概述基本语法编译器指令概述 基本语法 var关键字&#xff1a;定义变量&#xff0c;使用$来引用变量。变量是全局的并且是大小写敏感的寄存器变量&#xff1a;0 0 9,R0 R0 R9用于参数传递系统变量&#xff1a;用于特殊的用途 编译器指令 File:释放文件到当前输出路径 如…

2/17考试总结

时间安排 7:40–7:50 读题&#xff0c;T1 貌似是签到&#xff0c;T2,T4 DP,T3看起来很不可做。 7:50–8:00 T1,差分一下然后模拟就行了。 8:00–10:20 T2,注意到值域很小&#xff0c;可以考虑状压&#xff0c;想到一个状压状态数较少的 dp &#xff0c;然后挂得彻底。发现有一…

linux用户空间、内核空间

一、进程理解 进程&#xff1a;资源分配的最小单元&#xff0c;程序在操作系统中运行的实例 线程&#xff1a;最小调度单元 一个进程至少有一个线程或多个线程&#xff0c;一个线程只能属于一个进程&#xff0c;因为进程是最小的资源分配单元&#xff0c;所以线程不存在独立…

【LVGL笔记】-- 贝塞尔曲线绘制

什么是贝塞尔曲线 贝塞尔曲线&#xff08;Bzier Curve&#xff0c;也被称为贝塞尔多项式&#xff08;Bzier Polynomial&#xff09;&#xff0c;是由一系列控制点&#xff08;Control Point&#xff09;所定义的一条平滑曲线。Pierre Bzier于1960年开始利用该曲线设计雷诺的车…