Swift笔记 - 03.枚举类型、可选项
Swift笔记 - 03.枚举类型、可选项
枚举的关联值
- 有时会将枚举的成员值跟其他类型的关联存储在一起,会非常有用
enum Score {
case points(Int)
case grade (Character)
}
var score = Score.points(96)
score = .grade("A")
switch score {
case let .points(i):
print(i, "points")
case let .grade(i):
print("grade", i)
} // grade A
enum Date {
case digit(year: Int, month: Int, day: Int)
case string(String)
}
var date = Date.digit (year: 2011, month: 9, day: 10)
date = .string("2011-09-10")
switch date {
case .digit(let year, let month, let day) :
print(year, month, day)
case let .string(value):
print(value)
}
- 必要时
let
也可以改为var
枚举原始值
- 枚举成员可以使用相同类型的默认值预先关联,这个默认值叫做:原始值
enum PokerSuit: Character {
case spade = "♠️"
case heart = "♥️️"
case diamond = "♦️"
case club = "♣️"
}
var suit = PokerSuit.spade
print(suit) // spade
print(suit.rawValue) // ♠️
print(PokerSuit.club.rawValue) // ♣️
enum Grade: String {
case perfect = "A️"
case great = "B"
case good = "C"
case bad = "D"
}
print(Grade.perfect.rawValue) // A
print(Grade.great.rawValue) // B
print(Grade.good.rawValue) // C
print(Grade.bad.rawValue) // D
- 如果枚举的原始值类型是Int、String,Swift会自动分配原始值
enum Direction: String {
case north = "north"
case south = "south"
case east = "east"
case west = "west"
}
// 等价于
enum Direction: String {
case north, south, east, west
}
print(Direction.north) // north
print(Direction.north.rawValue) // north
enum Season: Int {
case spring, summer, autumn, winter
}
print (Season.spring.rawValue) // 0
print(Season.summer.rawValue) // 1
print (Season.autumn.rawValue) // 2
print (Season.winter.rawValue) // 3
enum Season: Int {
case spring = 1, summer, autumn = 4, winter
}
print(Season.spring.rawValue) // 1
print (Season.summer.rawValue) // 2
print (Season.autumn.rawValue) // 4
print(Season.winter.rawValue) // 5
递归枚举
indirect enum ArithExpr {
case number(Int)
case sum(ArithExpr, ArithExpr)
case difference(ArithExpr, ArithExpr)
}
enum ArithExpr {
case number(Int)
indirect case sum(ArithExpr, ArithExpr)
indirect case difference (ArithExpr, ArithExpr)
}
let five = ArithExpr.number(5)
let four = ArithExpr.number(4)
let two = ArithExpr.number(2)
let sum = ArithExpr.sum(five, four)
let difference = ArithExpr.difference(sum, two)
func calculate(_ expr: ArithExpr) -> Int {
switch expr {
case let .number(value):
return value
case let .sum(left, right):
return calculate(left) + calculate(right)
case let .difference(left, right):
return calculate(left) - calculate(right)
}
}
calculate(difference)
可选项
可选项绑定
- 可以使用可选项鄉定来判断可选项是否包含值
- 如果包含就自动解包,把值赋给一个临时的常量(
let
)或者变量(var
),并返回true
,否则返 回false
if let number = Int ("123") {
print("字符串转换整数成功:\(number)")
//number是强制解包之后的Int值
//number作用域仅限于这个大括号
} else {
print("字符串转换整数失败")
}
//字符串转换整数成功:123
enum Season: Int {
case spring = 1, summer, autumn, winter
}
if let season = Season(rawValue: 6) {
switch season {
case .spring:
print("the season is spring")
default:
print("the season is other")
}
} else {
print("no such season")
}
// no such season
if let first = Int ("4") {
if let second = Int("42") {
if first < second && second < 100 {
print("\(first) < \(second) < 100")
}
}
}
// 4 < 42 < 100
if let first = Int("4"),
let second = Int("42"),
first < second && second < 100 {
print("\(second) < \(second) < 100")
}
// 4 < 42 < 100
//遍历数组,将遇到的正数都加起来,如果遇到负数或者非数字,停止遍历
var strs=["1o","20","abc","-20","30"]
var index = 0
var sum = 0
while let num = Int(strs[index]), num > 0 {
sum += num
index += 1
}
print(sum)
guard 语句
guard 条件 else {
// do something...
退出当前作用域
// return, break. continue, throw error
}
- 当guard语句的条件为false时,就会执行大括号里面的代码
- 当guard语句的条件为true时,就会跳过guard语句
- guard语句特别适合用来“提前退出”
- 当使用guard语句进行可选项都定时,绑定的常量(let)、变量(var)也能在外层作用域中使用
func login(_ info: [String: String]) {
guard let username = info["username"] else {
print("请输入用户名")
return
}
guard let password = info["password"] else {
print("请输入密码")
return
}
// if username
// if password
print("用户名: \(username)", "密码:\(password)", "登陆ing")
}
隐式解包
- -在某些情况下,可选项一旦被设定值之后,就会一直拥有值
- 在这种情况下,可以去掉检查,也不必每次访问的时候都进行解包,因为它能确定每次访问的时候都有值
- 可以在类型后面加个感叹号!定义一个隐式解包的可选项
let num1: Int! = 10
let num2: Int = num1
if num1 != nil {
print(num1 + 6) // 16
}
if let num3 = num1 {
print(num3)
}
let num1: Int! = nil
// Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value
let num2: Int = num1
多重可选项
var num1: Int? = 10
var num2: Int?? = num1
var num3: Int?? = 10
print(num2 == num3) // true
- 可以使用
lldb
指今frame variable -R
成者fr v -R
查看区别
var numl: Int? = nil
var num2: Int?? = num1
var num3: Int?? = nil
print(num2 == num3) // false
(num2 ?? 1) ?? 2 // 2
(num3 ?? 1) ?? 2 // 1
空合并运算符??
public func ?? <T>(optional: T?, defaultValue: @autoclosure () throws
-> T?) rethrows -> T?
public func ?? <T> (optional: T?, defaultValue: @autoclosure () throws
-> T) rethrows -> T
- a ?? b
- a 是可选项
- b 是可选项或者不是可选项
- b 跟a的存储类型必须相同
- 如果a不为nil,就返回a
- 如果a为nil,就返回b
- 如果b不是可选项,返回a时会自动解包