swift基础——可选项
2022-03-14 本文已影响0人
夜凉听风雨
- 在swift里,声明一个变量或者常量,如果不是可选项的,是没有默认值的,使用前必须要赋值。
var name:String
print(name) // 报错
必须要赋值
var name:String = " "
print(name) // 正确的
- 设置为可选项默认值为nil
var name:String?
print(name) // nil
- 可选项可以用来做函数返回值类型
let arr = [1,2,3]
func searchNumber(index: Int) -> Int? {
if index < 0 || index >= arr.count {
return nil
} else {
return arr[index]
}
}
print(searchNumber(index: 1)) // Optional(2)
print(searchNumber(index: -1)) // nil
print(searchNumber(index: 4)) // nil
强制解包
-
可选项是对其他数据类型进行了一层包装,直接使用就是Optional()包装起来的。
-
如果需要拿到内部的数据需要使用感叹号!来进行强制解包。
-
但是如果是nil强制解包运行时会报错,所以需要进行空判断
-
判断可选项是否包含值
let num = Int("ab123") // 这种方式生成的Int型是可选型
if num == nil {
print("转换失败")
} else {
print("转换结果为\(num!)")
}
-
可以使用可选项绑定来判断可选项是否包含值
如果包含就自动解包,把值赋给一 个临时的常量(let)或者变量(var) ,并返回true ,否则返回false
var num: Int? = 123
if let temp = num {
// temp为临时的解包后的值
print("值为\(temp)")
} else {
print("值为空")
}
-
等价写法
如果有多次条件判断,可以省略多次的if ,用逗号,隔开。
if let num1 = Int("5") {
if let num2 = Int("1") {
if num1 > num2 {
print("\(num1) > \(num2)")
}
}
}
等价于
if let num1 = Int("5"),
let num2 = Int("1"),
num1 > num2 {
print("\(num1) > \(num2)")
}
-
while循环中使用可选项绑定
下面是一个打印数组中的正数,遇到非正数停止遍历的代码
let arr = ["10", "20", "-30", "40"]
var index = 0
while let num = Int(arr[index]), num > 0 {
index += 1
print(num)
}
空合并运算符??
方法定义.png-
a ?? b
1、a是可选项
2、b是可选项或者不是可选项
3、b跟a的存储类型必须相同
4、如果a不为nil,就返回a
5、如果a为nil ,就返回b
6、如果b不是可选项,返回a时会自动解包
var a : Int? = 10
var b = Int("20")
print(a ?? b) // Optional(10)
var a : Int? = nil
var b = Int("20")
print(a ?? b) // Optional(20)
var a : Int? = 10
var b = 20
print(a ?? b) // 10
var a : Int? = nil
var b : Int? = nil
print(a ?? b) // nil
// 多个??一起使用
var a : Int? = nil
var b : Int? = nil
print(a ?? b ?? 3) // 3
- ??跟if let配合使用
let a: Int? = nil
let b: Int? = 2
if let c = a ?? b {
print(c) // 2
} // 类似于if a != nil || b != nil
guard语句
// 语法
guard 条件 else {
// do something...
退出当前作用域
// return、break、continue、throw error
}
-
当guard语句的条件为false时,就会执行大括号里面的代码
-
当guard语句的条件为true时,就会跳过guard语句
-
guard语句特别适合用来“提前退出”
-
当使用guard语句进行可选项绑定时,绑定的常量(Let)、变量(var)也能在外层作用域中使用
let info = ["username":"jonas", "password":"12345"]
func login(info: [String : String]) {
guard let username = info["username"] else {
print("请输入用户名")
return
}
guard let password = info["password"] else {
print("请输入密码")
return
}
print("用户名=\(username)密码=\(password)")
}
login(info: info)
隐式解包
- 在某些情况下,可选项一旦被设定值之后,就会一直拥有值
- 在这种情况下,可以去掉检查,也不必每次访问的时候都进行解包,因为它能确定每次访问的时候都有值
- 可以在类型后面加个感叹号!定义一个隐式解包的可选项
- 定义了隐式解包后,在需要取里面的值时不需要再加!解包了,因为会自动隐式解包。
var num1: Int! = 10 // Optional(10)
var num2: Int = num1 // 10
var num3 = num1 // Optional(10)
var num4 = num1 + 5 // 15
字符串插值
可选项在字符串插值或者直接打印时,编译器会发出警告
var age: Int? = 10
print("age=\(age)") // age=Optional(10)
至少有3种方法消除警告
var age: Int? = 10
print("age=\(age!)") // age=10
print("age=\(age! ?? 0)") // age=10
print("age=\(String(describing: age))") // age=Optional(10)
多重可选项
var num1: Int? = 10 // Optional(10)
var num2: Int?? = num1 // Optional(Optional(10))
var num3: Int?? = 10 // Optional(Optional(10))
print(num2 == num3) // true
num1是一个Int型可选项,num2是一个Int型可选项的可选项,num3也是一个Int型可选项的可选项。
多重可选项在直接赋值一个值的时候,会直接包装为多重可选项。
var num1: Int? = nil // nil
var num2: Int?? = num1 // Optional(nil)
var num3: Int?? = nil // nil
print(num1 == num3) // false
print(num2 == num3) // false
(num2 ?? 1) ?? 2 // num2是Optional(nil)不为空所以(num2 ?? 1)是num2!也就是nil,所以(nil ?? 2)结果为2
(num3 ?? 1) ?? 2 // num3是nil,所以 (num3 ?? 1) 结果是1
如果多重可选项直接设置为nil的情况下,不会重复包装。
image.png