写在前面
swift今天发布了4.2的版本了,从3.0开始,swift逐渐趋向于稳定,最近在看看一些新的机会,也发现好多都要求会swift,3.0的时代写过一个程序,之后就很少用到这个东西了,总结记录一下,提醒自己不要忘了。
关于objcet-c和swift中对于nil的处理
Objective-C中的nil:表示缺少一个合法的对象,是指向不存在对象的指针,对结构体、枚举等类型不起作用(会返回NSNotFound)
Swift中的nil:表示任意类型的值缺失,是一个确定的值,要么是该类型的一个值要么什么都没有(即为nil)
一、申明可选常量或变量
let status: Int? = 1 // 申明可选Int类型的常量,初始值为1
var defaultAddress: String? = "江苏南京" // 申明可选String类型的变量,初始值为"江苏南京"
var student: Person? // 申明可选Person(自定义的类)的变量,初始值为nil
注意:Int?与Int不相同,Int?表示可选的Int类型,可以赋值为nil,而Int不可以赋值为nil
二、使用”!”强制解析获取可选类型的值(不建议直接使用)
var defaultAddress: String? = "江苏南京"
if defaultAddress != nil { // !=或==可以用来判断是否为nil
print("您的地址是\(defaultAddress!)") // 使用!强制解析
} else {
print("对不起,您不存在地址信息")
}
var student: Person?
print("学生为\(student!)") // XCode会提示运行错误,因为student初始值为nil,强制解析不行
三、使用可选绑定获取可选类型的值(建议的用法)
var defaultAddress: String? = "江苏南京"
if let address = defaultAddress { // 如果defaultAddress有值或类型转换成功,则将值赋值给address直接使用
print("您的地址是\(address)") // 使用address代替defaultAddress,且不需要加!强制解析
} else {
print("对不起,您不存在地址信息")
}
四、隐式解析可选类型(用于申明时肯定有初始值,但后面可能为nil)
var mobileNumber: Int64! = 13912345678 // 第一次申明有初始值
print("您的电话号码是\(mobileNumber)") // 不需要使用!强制解析
// 打印内容:**您的电话号码是****Optional(13912345678)**
// 还是不建议直接强制解析,因为实际项目中可能中间已经对该值做了改变,若为nil则会运行错误导致APP崩溃
if let number = mobileNumber { // 建议的做法
print("您的电话号码是\(number)")
// 打印内容:**您的电话号码是****13912345678**
} else {
print("您没有记录电话号码")
}
空合运算符(用于判断变量或常量是否为nil)
// 空合运算符:a ?? b 判断a是否为nil,若a不为nil对a解封,否则返回b的值
var status: Int? // 申明可选Int类型的变量status,初始值为nil
status ?? 0 // 因为status为nil,则返回0
// ?? 即为以下if else的缩写
func testOption() -> Int {
let status: Int? = 1
if status == nil {
return 0
} else {
return status!
}
}
六、函数/方法返回类型为可选类型
A:返回值为可选类型的值(如Int?、String?、(Int, String)?、[Int]?、[Int: String]?等)
func returnPossibleValue(value: Bool) -> String? { // 返回类型为可选String类型
if value {
return "返回类型是可选类型值" // 如果为真,返回Int类型的值1
} else {
return nil // 如果为假,返回nil
}
}
let possibleValue = returnPossibleValue(value: true) // 要用可选绑定判断再使用,因为possibleValue为String?可选类型
if let value = possibleValue {
print(value)
} else {
print("none value")
}
B:返回值为可选类型的类(如URL?、自定义Person?等)
class SomeClass {
var someValue: Int
init?(someValue: Int) { // 可失败构造器
if someValue == 1 { return nil }
self.someValue = someValue
}
}
func returnPossibleClass(value: Bool) -> SomeClass? { // 返回的类实例可能为nil
if value {
return SomeClass(someValue: 1) // 返回的为nil
} else {
return SomeClass(someValue: 2) // 返回的SomeClass?实例,不为nil
}
}
C:返回值为可选类型的闭包(如(()-> (void))? )
func returnOptionalFunc(value: Bool) -> (() -> (Void))? { // 返回类型为可选类型的闭包
if value {
return { () in
print("返回类型是可选类型闭包")
}
} else {
return nil
}
}
let possibleFunc = returnOptionalFunc(value: true) // 要用可选绑定判断再使用,因为possibleFunc 为可选类型的闭包,类型为() -> (Void)
if let aFunc = possibleFunc {
print(aFunc()) // 注意增加()调用闭包,因为没有参数则是空括号
} else {
print("none func")
}
七、可选类型在类或结构体中的运用
A:可选类型在类中的运用
class PossibleClass {
var someValue: Int
var possibleValue: String? // 可选存储属性,默认值为nil
init(someValue: Int) { // 构造方法中可以不对possibleValue属性初始化
self.someValue = someValue
}
}
let someClass = PossibleClass(someValue: 4) // 实例化对象时不需要对possibleValue初始化,someClass实例中:someValue为4,possibleValue为nil
注意:类中所有属性都需要有默认值。属性可以在申明时赋予初始值,也可以在构造方法中赋予初始值;子类继承父类时,必须先给自身属性先初始化后再继承父类构造方法初始化。一般的,出于安全的因素,子类的属性都赋予初始值或直接定义为可选类型。
B:可选类型在结构体中的运用
struct PossibleStruct {
var someValue: Int
var possibleValue: String? // 可选存储属性,默认值为nil
// 结构体中可以自定义一个init构造器对属性初始化,也可以不自定义
}
let someStruct = PossibleStruct(someValue: 4, possibleValue: nil)