最近学习Swift,也在Playground上敲了些代码,虽然说Swift类似于Java,可从Java转过来后我还是习惯地判空,像下面这个简单的判断:
String name = "sunfusheng";
if (name != null) {
// balabala...
}
但是在Swift中却不行,因为什么呢?原因在于Swift是强类型语言,注重代码的健壮与安全。那我还想判空,怎么解?学到Swift的可选型问题迎刃而解。
可选型(Optional)
public enum Optional<T> {
case None
case Some(T)
}
可以看出可选型是个泛型,而Optional又是个枚举 enum,Optional可以是 None,也可以是Some(T)。
声明可选型
显式声明
"?" 是 Optional<T> 的简写形式。
var name:Optional<String> = "sunfusheng"
var blog:String? = "sunfusheng.com"
// 现在就可以判断啦
if name != nil {
print(name)
}
print(blog)
// 输出
Optional("sunfusheng")
Optional("sunfusheng.com")
隐式声明
"!" 是 ImplicitlyUnwrappedOptional<T> 的简写形式。
var name1:ImplicitlyUnwrappedOptional<String> = "sunfusheng"
var blog1:String! = "sunfusheng.com"
print(name1)
print(blog1)
// 输出
sunfusheng
sunfusheng.com
可选型解包
Swift 中 String 和 Optional<String> 不是一个类型的,因为 Swift 是强类型语言,String 类型 和 Optional<String> 类型数据拼接肯定报错的,所以我们需要解包后使用。反过来说,Java 是弱类型语言,随便加,随便拼接。
强制解包
// 显式声明的可选型变量后加 "!" 强制解包
var name:String? = "sunfusheng"
"My name is " + name!
// 不建议使用强制解包,下面就会报错
name = nil
"My name is " + name!
// 隐式声明的可选型不需要解包,同样可能因为 nil 报错
var blog:String! = "sunfusheng.com"
// blog = nil
"My blog is " + blog
if let 解包可选型
// 可以使用相同的变量名解包
if let errorCode = errorCode {
print(errorCode)
}
// if let 可以同时解包多个变量,同样可以使用控制转移的条件
if let errorCode = errorCode, errorMessage = errorMessage where errorCode == "404" {
print("Page not found")
} else {
print("No error")
}
可选链 (Optional Chaining)
使用可选链 (Optional Chaining) 的方式来调用可能为空(nil)的方法,比如下面的代码
// 把我的名字全变成大写字母
var name:String? = "sunfusheng"
if let name = name {
print(name.uppercaseString)
}
// 输出
SUNFUSHENG
// 更优雅地使用可选链实现
print(name?.uppercaseString)
// 输出
SUNFUSHENG
// 如果 name = nil 就不会继续执行 uppercaseString
name = nil
print(name?.uppercaseString)
// 输出
nil
当然也可以使用强制解包方式使用可选链,当然不建议使用,除非你确保它不为 nil
print(name!.uppercaseString)
// 输出
SUNFUSHENG
// 编译不过,报错
name = nil
print(name!.uppercaseString)
Swift 可选型的强大之处可见一斑,以后的开发必然会经常用到的。
Swift 学习笔记将持续更新,欢迎关注我的公众号,大家加油!