持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第1天,点击查看活动详情
本章开始学习条件控制语句,包括if、while、for、switch、guard语句。包括语法讲解和代码演示。
主要内容:
- if分支语句
- while循环语句
- for循环
- switch语句
- guard语句
1、if分支语句
if分支语句和在语法结构上和其他语言基本一样,只是需要注意写法上有一定不同。
代码示例:
let age = 4
if age >= 5 {
print("大于22")
} else if age < 5 {
print("小于5")
}
说明:
- 比较的值为4,小于5,所以会打印“小于5”
- if后面的条件可以省略小括号()
- 条件后面的大括号{}不可以省略
注意:
- if后面的条件必须是bool类型,这个与OC不一样
2、while循环语句
代码示例:
//while循环
var num = 5
while num > 0 {
print("num is \(num)")
num -= 1
}
//repeat...while循环
var num2 = -1
repeat {
print("num is \(num)")
} while num > 0
说明:
- 有两种方式,一种是while循环,一种是repeat...while循环
- repeat...while循环就完全可以看做do...while
- while后面的判断条件不需要加()
注意:
- 注意在swift中没有自增和自减运算符,所以这里只能使用num -= 1 来自减
3、for循环语句
Swift给for循环语句显式的提供了for循环的区间,并且增加很多范围区间的种类,开发者对于for循环有更多的可操作性。
3.1 显式区间
可以显式的设置区间的范围
闭区间:
/*
1、简单循环获取i值(变量)
*/
for var i in 1...3 {
i += 5
print(i)
}
/*
2、循环获取数组值
*/
let name = ["A","B","C"]
for i in 0...3 {
print(name[i])
}
/*
3、可以将区间设置为变量来使用
*/
let range = 1...3
for i in range {
print(name[i])
}
/*
4、也可以用变量分开设置区间的左右范围
*/
let a = 1
var b = 2
for i in a...b {
print(name[i])
}
/*
5、不获取变量值
*/
for _ in 1...3 {
print("WY")
}
说明:
- 在使用上就是直接通过a...b这种方式来设置for循环的区间,这种属于闭区间,表示(a<= 取值 <= b)
- 我们可以直接将左右区间的范围写死,也可以将左右区间范围设置为变量,以此达到动态设置的效果
- 甚至可以将区间整个赋值给一个变量,后续循环时使用这个变量
- 循环拿到的值默认是常量let,是无法再次赋值的,如果想要再次赋值,就需要设置为变量var
- 如果不需要获取循环的变量值,可以使用_来表示,这样就可以节省栈空间
- 数组的获取也就是简单的数组名加下标值来获取
半开区间:
/*
半开区间
*/
for i in 1..<5 {
print(i)
}
说明:
- 在使用上就是直接通过a..<b(a<..b)这种方式来设置for循环的区间,这种属于半开区间,表示a<= 取值 < b (a< 取值 <= b)
3.2 增强for
区间运算符直接作用在数组上。
实例代码:
/*
1、直接获取数组中的数据
*/
let names = ["A","B","C"]
for name in names[0...3] {
print(name)
}
说明:
- 既可以通过name加下标来获取
- 也可以通过增强for,直接获取到数组元素
单侧区间:
让区间朝一个方向尽可能远
/*
2、单侧区间
*/
for name in names[1...] {
print(name)
}
说明:
- 单侧区间就是只设置其中一侧的范围,另一侧是无限远
- 当然不可能是真的无限远,否则就死循环了,而是到达数组的最大下标
- 在增强for的语法中可以使用单侧区间。因为这样就不会死循环。
3.3 设置区间类型
Swift内置了区间类型供我们在不同场景不同需求下方便使用
var range1: ClosedRange<Int> = 1...3
var range2: Range<Int> = 1..<3
var range3: PartialRangeThrough<Int> = ...5
range1 = 2...4
for i in range1 {
print(i)
}
说明:
- Swift提供了很多内置的区间类型,我们可以使用这些类型创建区间变量进行使用
- ClosedRange是闭区间,左右两侧都是闭区间,包含1和3
- Range是半开区间,左侧闭区间,右侧开区间。所以代码中只包含1,不包含3
- PartialRangeThrough是单侧区间,左侧无限远,可以用在增强for中查找数组
字符、字符串使用区间运算符:
let stringRange = "a"..."f"
stringRange.contains("d")//true
stringRange.contains("h")//false
说明:
- 字符、字符串也能使用区间运算符,但是默认不能用在for- in中
- 可以直接使用这些区间类型,来设置字符
- 并且可以使用类型的方法来进行处理
3.4 where过滤变量值
代码示例:
/*
where过滤
*/
var numbers = [10,20,-11,-22]
var sum = 0
for num in numbers where num > 0 {
sum += num
}
print(sum)
说明:
- 可以看到会使用num>0增加了for循环的判断
- 其他条件还和之前一样,只不过在进行循环执行时,会进行一下where的判断
- 如果不符合条件就不会再进入,但是仍然会执行下一次的循环。这里的where判断与循环无关。
- 如果符合条件就会进入执行
3.5 设置区间间隔
代码示例:
let hours = 10
let hourInterval = 2
//tickMark的取值:从4开始,累加2,到达10结束,包含10
for tickMark in stride(from: 4, through: hours, by: hourInterval){
print(tickMark)
}//4,6,8,10
//tickMark的取值:从4开始,累加2,到达10结束,不包含10
for tickMark in stride(from: 4, to: hours, by: hourInterval){
print(tickMark)
}//4,6,8
说明:
- 也可以设置循环的区间间隔,分别设置累加值和终止值
- 通过stride来设置,包含三个参数:开始值、累加值、终止值
- 终止值有两种,如果是through,则包含最后一个值,如果是to则不包含
- 所以在代码案例中,第一种使用through,打印4,6,8,10,包含10
- 第二种使用to。打印4,6,8,不包含10。
4、switch语句
4.1 基础用法
代码示例:
/*
1、基础写法
*/
var number = 1
switch number {
case 1:
print("number is 1")
break
case 2:
print("number is 1")
break
default:
print("number is other")
break
}
/*
2、fallthrouth
*/
switch number {
case 1:
print("number is 1")
fallthrough
case 2:
print("number is 1")
default:
print("number is other")
}
/*
3、支持Character、String类型
*/
var str = "WY"
switch str {
case "A":
print("A")
case "B":
print("B")
case "WY":
print("WY")
default:
break
}
说明:
- 依然是通过switch+case来实现
- 注意case、default后面不能写大括号{}
- 与其他语言不一样的是默认已经有break,所以可以显式的写breake,不写也不会贯穿到后面条件
- 如果我们想要实现贯穿效果,需要加上fallthrough
- 需要注意的是switch也支持Character、String类型
注意:
- switch必须要能够实现处理所有的情况,其他情况可以放在default,如果已经确定已经包含所有情况,是可以不写default的
- case、default后面至少要有一条语句,如果不想做任何事情,就可以加个break
4.2 匹配类型
4.2.1 组合条件匹配
代码示例:
/*
组合匹配
*/
var str = "WY"
switch str {
case "A":
print("A")
case "B","WY":
print("B or WY")
default:
break
}//B or WY
说明:
- 可以有多个条件组合匹配,中间用,分割
- 组合条件是或的关系,只要有一个条件符合,就可以进入。
- str为WY,所以符合“WY”的条件,会打印B or WY
4.2.2 区间匹配
代码示例:
/*
2、区间匹配
*/
let count = 60
switch count {
case 0:
print("none")
case 1..<60:
print("a few")
case 10...100:
print("dozens of")
default:
print("other")
}//dozens of
说明:
- 在switch中也可以设置闭区间或半开区间来判断值的范围
- 我在这里将多个case写的有重合部分,这种情况,如果同时都满足,会优先执行前面的,因为默认会有break
- 代码案例中,count为60,而1..<60是半开区间,不包含60,所以会执行dozens of
4.2.3 元组匹配
代码示例:
/*
3、元组匹配
*/
let point = (1,1)
switch point {
case (0,0):
print("the origin")
case (_,0):
print("on the x-axis")
case (0,_):
print("on the y-axis")
case (-2...2,-2...2):
print("inside the 2*2 box")
default:
print("outside of the box")
}//inside the 2*2 box
说明:
- 判断的类型也可以是元组,元组是否在这个区间内
- 可以使用下划线_忽略这个值
- 元组的每个元素也可使用区间来判断,闭区间或半开区间
- 案例中判断一个点的位置是否在2*2的正方形中。
4.2.4 模式匹配
也可以使用模式匹配方式进行更大范围更详细的匹配 代码示例:
说明:
4.2.5 值绑定
可以在匹配的过程中获取其中的某个值 代码示例:
/*
5、值绑定
*/
let point2 = (2,0)
switch point {
case (let x,0):
print("on the x-axis with an x value of \(x)")
case (0,var y):
y += 2
print("on the x-axis with an x value of \(y)")
default:
break
}// on the x-axis with an x value of 2
说明:
- 此处我们在匹配元组时,只匹配了其中一个值,另一个值不进行匹配,而是用来获取的。
- 案例判断这个点的位置是在横坐标还是在纵坐标上。所以只需要判断x或y是否是0即可。
- 另一个值可以直接获取,在语句中进行使用
4.3 where过滤
代码示例:
let point3 = (1,-1)
switch point3 {
case let (x,y) where x == y:
print("on the line x == y")
case let (x,y) where x == -y:
print("on the line x == -y")
case let (x,y):
print("other")
}//on the line x == -y
说明:
- 可以通过where增加判断条件
- 和for循环中的where一样的作用,在对case的条件进行匹配时,增加一个判断条件。同时满足才可以进入
- 代码案例中没有加default,是因为最后的let (x,y)已经包含了所有情况。只要case的条件能包含所有情况就不需要default了
5、Guard语句
主要用于提前退出,条件不符合的时候退出,判断值是否成立用它就很方便了
代码示例:
func test(v: Bool) {
guard v else {
print("当条件为false时进入")
return
}
print("当条件为true时进入")
}
test(v: true)
test(v: false)
说明:
- 当guard语句的条件为false时,就会执行大括号里面的代码
- 当guard语句的条件为true时,就会跳过guard语句
- guard语句特别适合用来“提前退出”
- 代码案例中分别传入true和false,打断点进行查看执行的过程。
- 有时候我们想要判断传入的数据是否成立,如果不成立,就不再继续执行,就可以使用该语句来执行。