Swift开发小技巧系列 - 改造Optional
很多开发语言对nil
这个概念,也都有不同的处理。Swift也一样,但处理方式有所不同。Swift语言很巧妙创造一种新的类型:Optional
, 来修饰可以被赋值nil
的变量。有了Optional,可以确保明确处理nil
值,让你的程序更加安全。
什么是Optional?
我们先来看看源码
public enum Optional<Wrapped> : ExpressibleByNilLiteral {
case none
case some(Wrapped)
}
从上面,我们可以看到,Optional是一种枚举类型。并且一种有关联值(Associated Value)枚举。
如何使用Optional?
当我们定义变量时,其实我们只有两种选择,一种是optional类型的,另一种是non-optional的。这两种具体有什么区别,我们看下面代码。
// non-optional
var message: String = "Hello, World!" // 编译正常
message = nil // 编译出错
// optional
var name: String? = "Derek" // 编译正常
name = nil // 编译正常
从上面代码我们可以看出,non-optional类型的变量时不能被赋值nil
的。String
是non-optional类型,String?
是optional类型,它们是两种不同的类型,String
是表示字符串类型,String?
本质上是枚举类型,只是这个枚举类型的关联值类型为String
。Swift
语言设计为了安全性,需要你在声明变量时,明确这个变量是否是Optional类型。Swift编译器会以此为依据,在编译期间做相应的检查。
改造Optional
在对Optional类型有了基本了解以后,我们来更进一步。来看看实际开发中,有哪些使用场景需要我们改造下Optional,来让写程序变得更简单些。
场景一:获取UITextField
里面的text
,并判断是否为nil
或empty
一般我们会这么写:
guard let text = textField.text, !text.isEmpty else {
// handle for nil or empty
return
}
// Do something with text
因为UITextField的text属性的类型为String?,所有每次都要先解包(unwrap),再检查是否为空。需要两步,我们有没有办法一步解决呢?看下面代码
extension Optional where Wrapped == String {
public var nilIfEmpty: String? {
guard let value = self else { return nil }
return value.isEmpty ? nil : value
}
}
guard let text = textField.text.nilIfEmpty else {
// handle for nil or empty
return
}
// Do something with text
其实我们的目的就是把nil
和empty
当做同一种情况处理。这时候我们可以通过给Optional
加一个计算属性nilIfEmpty
,当Optional
的值为nil
或者empty
时,这个属性都会返回nil
。这样我们每次的处理代码,就只要使用一次解包(unwrap)操作就行了
场景二: 把let names = ["Derek", "", "John", "", "Tony", nil]
里面名字为nil
和empty
的过滤掉
这个需求使用我们自定义的nilIfEmpty
,实现起来非常简单,请看下面代码
let names = ["Derek", "", "John", "", "Tony", nil] // [String?]
let validNames1 = names.map { $0.nilIfEmpty } // [String?]
print(validNames1) // [Optional("Derek"), nil, Optional("John"), nil, Optional("Tony"), nil]
let validNames2 = names.flatMap { $0.nilIfEmpty } // [String]
print(validNames2) // ["Derek", "John", "Tony"]
参考资料
联系方式
备注
我们在软件开发的过程中,为了提高效率,其中很重要的一环就是把反复使用到的功能或模块封装起来。因此我在GitHub上开源了一个小工具集 - SwiftDevHints,来总结自己在实际项目开发过程中封装的一些小功能。
刚刚介绍的只是其中一个小功能,想看看其它更多功能,请直接点击SwiftDevHints。如果您觉得对您有所帮助,请给一个star吧。