Marks

iOS开发者,喜欢研究技术。

0%

Swift可选值

可选型optional ,表示一个值可能为空。但是这个空,在swift中就叫可选型,用关键字nil表示。它既不是0,也不是不存在,它就是nil

要么是它自身的值,要么为nilnil就是可选型的默认值

声明一个可选项

用: 字符类型+? 必须显示的申明

1
2
3
4
5
6
var errorCode:Int? = 404
var errorMessage:String? = "Not Found!"

errorCode = nil

print( errorMessage ) // 输出:Optional("Not Found!")

不能隐示的声明

1
2
3
4
5
6
7
8
9
10
//var errorCode1? = 404 //报错,必须声明类型

var errorCode2:Int? = 404 //得像这样,显示的申明一个类型

// Int? 和 Int 不是一种类型
let imInt = 405 //Int 型
errorCode = imInt
print(errorCode) //Optional(405)

//imInt = errorCode //报错了,把一个可选型赋值给一个Int型,报错。

可选型的解包。

解包就是我得使用它了。确认强制解包用:!

1
2
3
4
5
6
7
8
9
10
11
var errorCode3:String? = "404"

//"the errorcode is " + errorCode3 // 报错:2种不同的类型不能直接拼装使用。

//如果需要使用,就得解包。用强制解包:!
"the errorcode is " + errorCode3! // 打印:the errorcode is 404

//用强制解包,是很危险的,如果这个值真的为 nil。然后强制解包,就会报错。

var errorCode4:String? = nil
//"the errorcode is " + errorCode4! // 报错了:nil被强制解包报错。

可以用if 判断可选型是否为nil,安全后再用!解包

1
2
3
4
5
6
var errorCode5:String? = "502"
if errorCode5 != nil {
print(errorCode5!) //打印:502
} else {
print("No error!")
}

if 联合使用 let 关键字解包,可以不用!了

1
2
3
4
5
6
7
8
9
10
11
12
if let unwrappedErrorCode = errorCode5{
print(unwrappedErrorCode) //打印:502
} else {
print("No error!")
}

//也可以用相同的名字:
if let errorCode5 = errorCode5{
print(errorCode5) //打印:502
} else{
print("No error!")
}

使用 if let 解包多个可选型的值。相当于 and 操作

1
2
3
4
if let errorCode5 = errorCode5, errorMessage = errorMessage{
print("code is \(errorCode5), msg is \(errorMessage)")
//打印:code is 502, msg is Not Found!
}

使用 if let 再加 where 进一步限定

1
2
3
4
if let errorCode5 = errorCode5, errorMessage = errorMessage where errorCode5 == "502"{
print("code is \(errorCode5), msg is \(errorMessage)")
}
print(errorCode5) // 它自身的值并没有被改变:Optional("502")

使用 guard let,可以不用!了

1
2
3
4
5
6
7
8
let str: String? = ""
guard let newStr = str else {
print("str为nil")
//str为nil时,在这里会直接return
return
}
//下面使用newStr不用解包,newStr为非可选类型
print(newStr)

使用 guard let 解包多个可选型的值。相当于 and 操作

1
2
3
4
5
6
7
8
let str1: String? = ""
let str2: String? = ""
guard let newStr1 = str1, let newStr2 = str2 else {
print("str1或str2为nil")
return
}
print(newStr1)
print(newStr2)

Optional chaining 链式操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//解包
var errorMessage2: String? = "Not Found"
if let errorMessage2 = errorMessage2{
print(errorMessage2.uppercaseString) // "NOT FOUND" 全部大写了
}

//chaining操作就是可以直接用:

if let errorMessage2 = errorMessage2?.uppercaseString{
print(errorMessage2) // "NOT FOUND" 全部大写了
}

//也可以直接用 !强制解包,前提是你确定一定不为nil。
let upperMessage2 = errorMessage2!.uppercaseString //"NOT FOUND" 全部大写了

使用 ?? 解包。更加单的三目运算符

1
2
3
4
5
let message2 = errorMessage == nil ? "No error" : errorMessage!

//等价。如果 errorMessage 解包成功,就把解包的值给 message3
//如果 errorMessage 解包失败,message3的值为 "No error"
let message3 = errorMessage ?? "No error" // "Not Found!"

在元祖里面使用可选型

1
2
3
4
5
6
7
8
9
10
11
12
13
//errorMessage 设置为可选
var error1:(errorCode:Int, errorMsg:String?) = (404, "Not found!")

error1.errorMsg = nil //成功

print(error1) //打印:(404, nil)

//把整个元祖设置为可选
var error2:(errorCode:Int, errorMsg:String)? = (404, "Not Found!")

error2 = nil //成功的

print(error2) // 打印:nil

摘自