# Swift5.0 - day2-流程控制、函数、枚举（上）

## 一、流程控制

• 1.1、if 语句

let age = 5
if age > 10  {
print("\(age) 大于 10 ")
} else if  age > 3 {
print("\(age) 大于 3 ")
} else {
print("\(age) 小于 3 ")
}

• if 后面的条件可以省略小括号，而条件后面的花括号不可以省略
• if 后面的类型只能是 bool 类型

• 1.2、while 语句(先判断后执行)

var num = 5
while num > 0 {
num -= 1
print("num=\(num)")
}
• 打印结果：num=4、num=3、num=2、num=1、num=0
• 1.3、repeat while 语句(先执行后判断)

var num = -1
repeat{
print("num=\(num)")
}while num > 0
• 打印结果：num=-1，

• 1.4、for 语句
• 闭区间运算符：a...ba<= 取值 <=b

let names = ["小1","小2","小3","小4"]
for i in 0...3 {
print("name=\(names[i])")
}

let a =  0
var b = 3
let names = ["小1","小2","小3","小4"]
for i in a...b {
print("name=\(names[i])")
}

for _ in 0...3 {
print("😆")
}

• for 循环里面的 i 默认是 let，有需要的时候我们可以声明为 var,如下

for var i in 1...3 {
i += 2
print("i=\(i)")
}
• 打印结果：3、4、5
• 半开区间运算符：a..<ba <= 取值 < b

for i in 1..<3 {
print("i=\(i)")
}
• 打印结果：1、2
• 1.5、for - 区间运算符用在数组上
• 例一

let names = ["小1","小2","小3","小4"]
for name in names[0...3] {
print("name=\(name)")
}
• 打印结果：小1、小2、小3、小4
• 例二：单侧区间：让区间朝一个方向尽可能的远

let names = ["小1","小2","小3","小4"]
for name in names[1...] {
print("name=\(name)")
}
• 打印结果：小2、小3、小4

let names = ["小1","小2","小3","小4"]
for name in names[...2] {
print("name=\(name)")
}
• 打印结果：小1、小2、小3

let names = ["小1","小2","小3","小4"]
for name in names[..<2] {
print("name=\(name)")
}
• 打印结果：小1、小2

let range = ...5
print(range.contains(8))
print(range.contains(3))
print(range.contains(-1))
• 打印结果：false、true、true

• 1.6、区间类型（重点）

let range1:ClosedRange<Int> = 1...3
let range2:Range<Int> = 1..<3
let range3:PartialRangeThrough<Int> = ...5
• 字符、字符串也能进行区间运算，但默认不能在 for-in 中，因为 ClosedRange：不可数的闭区间

let stringRange1 = "cc"..."ff" // ClosedRange<String>
stringRange1.contains("cb")   // false
stringRange1.contains("dz")   // true
stringRange1.contains("fg")   // false
let stringRange2 = "a"..."f"  // ClosedRange<String>
stringRange2.contains("d")    // true
stringRange2.contains("n")    // false

• 0到~包含了所有可能要用到的 ASCII 字符

let characterRange:ClosedRange<Character> = "\0"..."~"
characterRange.contains("b")   // true
• 1.8、带间隔的区间值

let hours = 12
let hourInterval = 2
// 从tickMark 的取值：从 4 开始，累加2，不超过 12
for tickMark in stride(from: 4, to: hours, by: hourInterval) {
print("tickMark=\(tickMark)")
}
• 打印结果：4、6、8、10
• 1.9、switch 语句
• 案例一：switch的基本使用

var num = 10
switch num {
case 1:
print("值是1")
break
case 2:
print("值是2")
break
case 3:
print("值是3")
break
default:
print("没有匹配")
break
}

• 案例二：使用 fallthrough 可以实现贯穿效果

var num = 1
switch num {
case 1:
print("num 值是 1")
fallthrough
case 2:
print("num 值是 2")
case 3:
print("num 值是 3")
default:
print("没有匹配")
}
• 打印结果：num 值是 1、num 值是 2
• switch使用注意点：
• <1>、switch 必须能保证处理所有的情况

• <2>、case 或者 default 后面至少有一条语句，如果不想有语句可以写 break

var num = 1
switch num {
case 1:
print("num 值是 1")
case 2:
break
default:
print("没有匹配")
}
• <3>、如果能保证处理所有的情况，也可以不必使用 default,如下

enum Answer {case right,wrong}
print("right")
print("wrong")
}

enum Answer {case right,wrong}
case .right:
print("right")
case .wrong:
print("wrong")
}
• 复合条件：switch也支持Character、String 类型，如下例子
• 例一：String 类型

let name = "marry"
switch name {
case "Jack":
print("Jack")
case "marry":
print("marry")
default:
print("找不到某人")
}
• 例二：String 类型

let name = "marry"
switch name {
case "Jack","marry":
print("Jack and marry")
default:
print("找不到某人")
}
• 例三：Character 类型

let character = "A"
switch character {
case "a","A":
print("字母 a或者A")
default:
print("找不到字母")
}
• 匹配区间和元组匹配
• 匹配区间

let count = 20
switch count {
case 0:
print("none")
case 1..<5:
print("a few")
case 5..<100:
print("several")
case 100..<1000:
print("hundreds of")
default:
print("many")
}
• 元组匹配

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 box")
default:
print("many")
}

• 值绑定：必要时，let 可以改为 var

let point = (2,0)
switch point {
case (let x,0):
print("on the x-axis with an x value of \(x)")
case (0,let y):
print("on the y-axis with an y value of \(y)")
case let (x,y):
print("somehere else at (\(x),\(y))")
}
• 1.10、where语句

let point = (2,-2)
switch point {
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("(\(x),\(y)) is just some arbitrary point")
}
• 例二：所有的正数相加

let numbers = [-1,2,3,-10,20]
var sum = 0
for num in numbers where num > 0 {
sum += num
}
print("最后正数的和=\(sum)")

• 1.11、标签语句

outer: for i in 1...4{
for k in 1...4 {
if k == 3 {
continue outer
}
if i == 3 {
break outer
}
print("i=\(i) k=\(k)")
}
}

## 二、函数

• 2.1、函数的定义：是一组代码的组合，因此函数也被称为完成特殊功能的代码块。函数三要素：函数名、参数、返回值。
• 有返回值，有参数

func pi()->Double{
return 3.14
}
print(pi())
func sum(num1:Int,num2:Int)->Int{
return num1 + num2
}
print(sum(num1: 1, num2: 3))

• 无返回值，无参数；下面的几种 无返回值表达的意思是一样的

func sayHello()->Void{
print("Hello")
}
func sayHello()->(){
print("Hello")
}
func sayHello(){
print("Hello")
}
• 2.2、函数的隐式返回

func sum(num1:Int,num2:Int) -> Int{
num1 + num2
}
sum(num1: 1, num2: 3)

• 2.3、返回元组 和 实现多值返回

func calculate(v1: Int,v2:Int) -> (sum:Int,difference:Int,average:Int){
let sum = v1 + v2
return (sum,v1-v2,sum>>1)
}
let result = calculate(v1: 20, v2: 10)
result.sum   // 和
result.difference  // 差 ： 10
result.average   // 二进制右移 是 平均值 15

/// 求和 【概述】
///
/// 将两个整数相加 【更详细的描述】
///
/// - Parameter v1: 第 1 个整数
/// - Parameter v2: 第 2 个整数
/// - Returns : 两个整数的和
///
/// - Note:传入两个整数即可 【批注】，有没有什么特殊的用法
///
func sum(_ v1:Int,_ v2:Int) -> Int{
return v1 + v2
}
sum(10, 20)

• 效果如下：

• 2.5、参数标签
• 可以修改参数标签

func goToWork(at time:String){
print("this time is \(time)")
}
goToWork(at: "08:00")
• 打印结果：this time is 08:00
• 可以使用下划线 _ 省略参数标签

func sum(_ v1:Int,_ v2:Int) -> Int{
return v1 + v2
}
sum(10, 20)
• 2.6、默认参数值(Default Parameter Value)
• 参数可以有默认值

func check(name:String = "noPerson",age:Int,job:String = "iOS"){
print("名字=\(name) 年龄=\(age) 工作=\(job)")
}
check(name: "老大", age: 19, job: "iOS")
check(name: "老二", age: 19)
check(age: 10, job: "前端")
check(age: 16)

• C++的默认参数值有个限制：必须从右往左设置。由于Swift拥有参数标签，因此并没有此类限制
• 但是在省略参数标签时，需要特别注意，避免出错，如下
这里的 two 不可以省略参数标签

func test(_ one:Int = 10,two:Int,_ three:Int = 20){
print("打印 one = \(one) two = \(two) three = \(three)")
}
test(two: 9)

func sum(_ numbers: Int...) -> Int {
var total = 0
for i in numbers {
total += I
}
}
sum(1,2,3)

func test(_ numbers:Int...,string:String,_ other:String){
}
test(1,2,3, string: "iOS", "Rose")

• 2.8、Swift 自带的 print 函数

/// - Parameters:
///   - items: Zero or more items to print.
///   - separator: A string to print between each item. The default is a single
///     space (" ").
///   - terminator: The string to print after all items have been printed. The
///     default is a newline ("\n").
public func print(_ items: Any..., separator: String = " ", terminator: String = "\n")
• 分析： 第一个参数是要打印的值，第二个参数是：连接第一个参数值的 字符，第三个参数是：默认是 \n 换行，如下例子
print(1,2,3,4,5)
print(1,2,3, separator: "_")
print(1,2,3, separator: "_", terminator: "")
print("哈哈")
• 打印结果是： 最后一行不换行，因为 "\n" 被用  "" 取代了

1 2 3 4 5
1_2_3
1_2_3哈哈
• 2.9、输入输出参数 (In-Out Parameter)
可以用 inout 定义一个输入输出函数：可以在函数内部修改外部实参的值

func swapValues(_ v1:inout Int,_ v2:inout Int){
let tem = v1
v1 = v2
v2 = tem
}
var num1 = 10
var num2 = 20
swapValues(&num1, &num2)
print(num1,num2)
• 打印结果：20 10
• 提示:下面的函数与上面的等价：传进去的是 内存地址，所以可以修改其外部参数的值

func swapValues(_ v1:inout Int,_ v2:inout Int){
(v1,v2) = (v2,v1)
}
• 可变参数不能标记为 inout
• 输入输出参数不能有默认值
• 输入输出参数不能传入常量（let）、字面量作为实参。也就是可以被多次赋值的 变量
• inout 参数的本质是地址传递 (引用传递)

规则：函数名相同
参数个数不同 || 参数类型不同 || 参数标签不同

func sum(v1:Int,v2:Int) -> Int{
return v1 + v2
}
• 参数个数不同

func sum(v1:Int,v2:Int,v3:Int) -> Int{
return v1 + v2
}
• 参数类型不同

func sum(v1:Int,v2:Double) -> Double{
return Double(v1) + v2
}
func sum(v1:Double,v2:Int) -> Double{
return v1 + Double(v2)
}
• 参数标签不同

func sum(_ v1:Int,_ v2:Int) -> Int{
return v1 + v2
}
func sum(a:Int,b:Int) -> Int{
return a + b
}
• 函数重载注意点一： 返回值类型 与 函数重载 无关

func sum(a:Int,b:Int) -> Int{
return a + b
}
func sum(a:Int,b:Int) {
}
sum(a: 1, b: 2)
• 函数重载注意点二：默认参数值和函数重载一起使用产生二义性时，编译器并不会报错(在 C++ 中会报错)

func sum(a:Int,b:Int) -> Int {
return a + b
}
func sum(a:Int,b:Int,c:Int = 10) -> Int {
return a + b + c
}
// 会调用 sum(a:Int,b:Int)，这样不太好，还不如编译器报错
sum(a: 1, b: 2)
• 函数重载注意点三：可变参数，省略参数标签，函数重载一起使用产生二义性时，编译器有可能会报错

func sum(a:Int,b:Int) -> Int{
return a + b
}
func sum(_ a:Int,_ b:Int) -> Int {
return a + b
}
func sum(_ numbers: Int...)->Int{
var total = 0
for i in numbers {
total += I
}
}

• 调用 sum(1,2) 报错：Ambiguous use of 'sum'

|
8天前
|

Swift 语言：什么是闭包（Closure）？它们与函数的区别是什么？
Swift 语言：什么是闭包（Closure）？它们与函数的区别是什么？
43 1
|
8天前
|
Swift
Swift中的函数
Swift中的函数
25 1
|
8天前
|

Swift中，函数和闭包
Swift中，函数和闭包
38 1
|
7月前
|
Swift iOS开发
23 Swift中如何定义和使用函数
Swift中如何定义和使用函数
56 0
|
8月前
|
Swift
Swift Debug 和 Release 中 print() 函数调试切换
Swift Debug 和 Release 中 print() 函数调试切换
45 0
|
Swift C语言

64 0
|
Swift C语言
【Swift 5.1】流程控制、函数与内联函数优化

189 0
|

Swift实用小册06:函数的定义、参数、返回、调用
Swift实用小册06:函数的定义、参数、返回、调用
204 0
【Swift4】(5) 函数基本使用 | 可变参数 | inout引用传递 | 函数类型返回值 | 函数嵌套
【Swift4】(5) 函数基本使用 | 可变参数 | inout引用传递 | 函数类型返回值 | 函数嵌套
160 0
|

Swift5.0 - day2-流程控制、函数、枚举（下）
Swift5.0 - day2-流程控制、函数、枚举（下）
68 0