IOS迷你教程3-Swift语言之流程控制(swift4.2)

告诉计算机在什么时候该做什么,称做控制流

在本教程中,您将学习如何来控制流程,从而让计算机听你的话。您还将了解布尔truefalse,以及如何使用它们来比较数据。

入门

此前学过了一些类型如IntDoubleString。在这里,您将学习另一种类型:布尔。

如,查找两个数字中的较大者,答案是truefalse

let yes = true // 类型推断为Bool
let no = false // 类型推断为Bool

布尔类型的值只能是truefalse

布尔运算符

布尔值通常用于比较值。例如,您可能有两个值,并且您想知道它们是否相等:值是相同的(true)还是它们是不同的(false)。

在Swift中,使用==执行此操作

let doesOneEqualTwo = (1 == 2)

swift推断doesOneEqualTwo是一个Bool。显然,1不等于2,因此doesOneEqualTwo将是false

同样,你可以看看两个值是否相等:

let doesOneNotEqualTwo = (1 != 2)

因为1不等于2,所以doesOneNotEqualTwo会是true

!取反操作

大于(>),小于(<):

let isOneGreaterThanTwo = (1 > 2)
let isOneLessThanTwo = (1 < 2)

isOneGreaterThanTwofalseisOneLessThanTwotrue

另外还有小于等于和大于等于:<=>=,同理。

布尔逻辑

&&。如果两个都是true,结果才是true。否则,结果是false

let and = true && true

在这种情况下,and将是true。如果右边的任何一个值是false,那么and就是false

||。只要其中一个为true,则结果为true。

let or = true || false

在这种情况下,or将是true。如果右边的两个值都是false,那么or就是false。如果两者都是true,那么or仍然是true

在Swift中,布尔逻辑通常应用于多个条件:

let andTrue = 1 < 2 && 4 > 3
let andFalse = 1 < 2 && 3 > 4

let orTrue = 1 < 2 || 3 > 4
let orFalse = 1 == 2 || 3 == 4

也可以这样:

let andOr = (1 < 2 && 3 > 4) || 1 < 4

字符串比较

在Swift,用于比较数字是否相等的==号也可以用来比较字符串:

let guess = "dog"
let dogEqualsCat = guess == "cat"

得出dogEqualsCat是一个布尔类型,为false

与数字一样,您不仅可以比较是否相等,还可以比较一个值是否大于或小于另一个值:

let order = "cat" < "dog"

这时是按英文字母顺序比较,ordertrue

if语句

流程控制的第一个也是最常见的是if,只有某个条件为true时才执行:

if 2 > 1 {
  print("Yes, 2 is greater than 1.")
}

这是一个简单的if语句。如果条件是true,则将执行大括号之间的代码。如果条件为false,则语句将不执行大括号之间的代码。

您可以扩展if语句:

let animal = "Fox"
if animal == "Cat" || animal == "Dog" {
  print("Animal is a house pet.")
} else {
  print("Animal is not a house pet.")
}

这里,如果animal等于"Cat"或者"Dog",那么语句将运行第一个代码块。如果animal不等于"Cat"或者"Dog",则将在else内运行,以下内容被打印到控制台:

Animal is not a house pet.

else if

let hourOfDay = 12
var timeOfDay = ""

if hourOfDay < 6 {
  timeOfDay = "Early morning"
} else if hourOfDay < 12 {
  timeOfDay = "Morning"
} else if hourOfDay < 17 {
  timeOfDay = "Afternoon"
} else if hourOfDay < 20 {
  timeOfDay = "Evening"
} else if hourOfDay < 24 {
  timeOfDay = "Late evening"
} else {
  timeOfDay = "INVALID HOUR!"
}
print(timeOfDay)

if语句将逐个测试多个条件,直到true。无论后面的else-if条件是否为true,仅执行第一条true后面的代码。

末尾的else子句来处理以上都为false的情况。

控制台将打印出以下内容:

Afternoon

封装变量

if语句引入了一个新的概念范围,这是一种通过使用大括号封装变量的方法。

如,某地兼职工资的规定为:在40小时之前每小时25美元,之后每小时50美元。

通过以下方式计算您的工资:

var hoursWorked = 45

var price = 0
if hoursWorked > 40 {
  let hoursOver40 = hoursWorked - 40
  price += hoursOver40 * 50
  hoursWorked -= hoursOver40
}
price += hoursWorked * 25

print(price)

结果如下:

1250

hoursOver40是在if语句中声明的新常量。如果这样会发生什么?

// ...

print(price)
print(hoursOver40)

这将导致以下错误:

Use of unresolved identifier 'hoursOver40'

此错误通知您,您只能在创建它的范围内使用hoursOver40常量。在这种情况下,if语句创建了一个新范围,因此当该范围结束后,您将无法使用该常量。

但是,每个范围都可以使用其父范围中的变量和常量。在上面的示例中,if语句内部仍然可以使用您在父范围中创建的pricehoursWorked变量。

三元运算

三元运算符即返回两个值中的一个,这取决于条件是true还是false

() ?  : 

这是一个找出两个变量中最小值的示例:

let a = 5
let b = 10

let min: Int
if a < b {
  min = a
} else {
  min = b
}

感谢三元运算符,您可以重写为简洁的代码:

let a = 5
let b = 10

let min = a < b ? a : b

如果a < btrue,则min的值为a;如果是falseminb

注意:如果过度使用,可能会牺牲代码的易读性。

循环

循环是多次执行代码的一种方式。在本节中,您将了解while循环。

循环时

while后面条件为true时,将循环执行大括号中的代码:

while  {
  
}

每一次循环,都会先检查条件。如果条件是true,则执行并准备下一次循环。一旦条件为false,则循环停止。就像if语句一样,while循环也引入了一个范围(大括号中的代码)。

最简单的while循环:

while true {
}

这是一个永远不会结束的while循环(死循环),因为条件总是true。一个死循环可能不会让程序崩溃,但很可能会让计算机死机。

强行退出

一个while循环示例:

var sum = 1

while sum < 1000 {
  sum = sum + (sum + 1)
}

此代码计算一个数学序列,直到sum值大于1000

循环执行如下:

循环迭代

在第九次迭代(循环)之后,sum1023,循环条件sum < 1000变为false,循环停止。

repeat-while循环

它与while循环的不同之处在于,在循环结束时判断条件是否为true

repeat {
  
} while 

这是上一节的示例,使用repeat-while循环:

sum = 1

repeat {
  sum = sum + (sum + 1)
} while sum < 1000

在此示例中,结果和之前相同。但并非所有的时候都是一样的。

while循环:

sum = 1
while sum < 1 {
  sum = sum + (sum + 1)
}

repeat-while循环:

sum = 1
repeat {
    sum = sum + (sum + 1)
}while sum < 1

while循环中,条件从一开始就是false。说明不会执行循环体,sum最终为1

repeat-while中,sum3,因为循环体将先执行一次。

跳出循环

有时你想早点结束循环。可以使用break语句,该语句会立即停止循环并继续循环后面的代码:

sum = 1

while true {
  sum = sum + (sum + 1)
  if sum >= 1000 {
    break
  }
}

条件为true,所以会永远循环。但一旦sum大于或等于1000,循环将结束。

高级控制流

在本节中,您将继续学习如何控制代码执行。您将了解另一个称为for循环的循环。

范围

在深入了解for循环语句之前,您需要了解一下ClosedRangeRange类型,它们可以表示一系列的数字。

封闭的范围:

let closedRange = 0...5

三个点(...)表示范围是从0到5(包括0和5)。即0, 1, 2, 3, 4, 5

半开放范围:

let halfOpenRange = 0..<5

范围是从0到5,包括0但包括5。即0, 1, 2, 3, 4

注意:
第二个数字必须始终大于或等于第一个数字。
范围通常用于for循环和switch语句中!

for循环

for  in  {
  
}

循环以for关键字开头,后面跟一个想在循环中使用的常量名,in后面为循环的范围:

let count = 10
var sum = 0

for i in 1...count {
  sum += i
}

i的初始值为1,也就是范围(1...count)的第一个数,每次循环之后都加1,直到等于count为止。

以下是每次迭代的isum的值:

对于循环迭代

i循环外部不可用。

当你在循环中不需要使用i时,可以用下划线:

sum = 1
var lastSum = 0

for _ in 0..

只是单纯的想让代码执行一定的次数,不需要用到循环常量(上述i)。
0..半开,表示代码将执行count次,这是一种需要执行多少次的常用方法。

也可以仅在某些条件下执行循环。如,想要计算总和但仅针对奇数:

var sum = 0
for i in 1...count where i % 2 == 1 {
  sum += i
}

wherefor循环中的一个子句。循环只会在where条件为true时执行循环体。

continue声明

有时你想跳过特定情况的循环迭代,而不想完全跳出循环。可以使用continue语句,该语句立即结束循环的当前迭代并开始下一次迭代。

8✕8乘法表:

full_board

假设您想要计算所有单元格的总和但排除所有偶数行:

first_board_example

使用for循环:

sum = 0

for row in 0..<8 {
  if row % 2 == 0 {
    continue
  }

  for column in 0..<8 {
    sum += row * column
  }
}

模2为0时,该行是偶数行。在这种情况下,continue跳出本次for循环,执行下一次循环。

break一样,continue也适用于for循环和while循环。

switch语句

控制流的另一种是switch语句,它允许您根据变量或常量的值执行不同的代码。

一个非常简单的switch语句:

let number = 10

switch number {
case 0:
  print("Zero")
default:
  print("Non-zero")
}

将输出:

Non-zero

case后面的值(本例中为0)表示:当number为此值时,执行冒号后面的语句。default表示以上全没有匹配到的话执行下面的代码。

另一个例子:

switch number {
case 10:
  print("It's ten!")
default:
  break
}

这次匹配到10,将执行case下面的代码。
break表示什么都不执行,

switch语句适用于任何数据类型!以下是切换字符串的示例:

let string = "Dog"

switch string {
case "Cat", "Dog":
  print("Animal is a house pet.")
default:
  print("Animal is not a house pet.")
}

这将打印以下内容:

Animal is a house pet.

case后接两个值,这说明如果等于"Cat"或者"Dog"将执行。

高级switch语句

case后接多种情况:

let hourOfDay = 12
var timeOfDay = ""

switch hourOfDay {
case 0, 1, 2, 3, 4, 5:
  timeOfDay = "Early morning"
case 6, 7, 8, 9, 10, 11:
  timeOfDay = "Morning"
case 12, 13, 14, 15, 16:
  timeOfDay = "Afternoon"
case 17, 18, 19:
  timeOfDay = "Evening"
case 20, 21, 22, 23:
  timeOfDay = "Late evening"
default:
  timeOfDay = "INVALID HOUR!"
}

print(timeOfDay)

将输出以下内容:
Afternoon

可以使用范围让代码更简洁:

var timeOfDay2 = ""

switch hourOfDay {
case 0...5:
  timeOfDay2 = "Early morning"
case 6...11:
  timeOfDay2 = "Morning"
case 12...16:
  timeOfDay2 = "Afternoon"
case 17...19:
  timeOfDay2 = "Evening"
case 20..<24:
  timeOfDay2 = "Late evening"
default:
  timeOfDay2 = "INVALID HOUR!"
}

print(timeOfDay2)

也可以像for循环一样使用where子句(先声明一个常量以便where子句中使用):

switch number {
case let x where x % 2 == 0:
  print("Even")
default:
  print("Odd")
}

这将打印以下内容:

Even

如for循环一样,声明的常量在下面的代码中不需要使用的话,可以用下划线代替:

switch number {
case _ where number % 2 == 0:
  print("Even")
default:
  print("Odd")
}

部分匹配

let coordinates = (x: 3, y: 2, z: 5)

switch coordinates {
case (0, 0, 0): // 1
  print("Origin")
case (_, 0, 0): // 2
  print("On the x-axis.")
case (0, _, 0): // 3
  print("On the y-axis.")
case (0, 0, _): // 4
  print("On the z-axis.")
default:        // 5
  print("Somewhere in space")
}

switch语句使用部分匹配

  1. 精确匹配(0, 0, 0)。说明时3D空间的原点。
  2. 匹配y = 0,z = 0和x可为任何值。说明坐标位于x轴上。
  3. 匹配x = 0,z = 0和y可为任何值。说明坐标位于y轴上。
  4. 匹配x = 0,y = 0和z可为任何值。说明坐标位于z轴上。
  5. 匹配其余坐标。

把上例中的下划线声明为变量,这样可以在case后面的语句中使用:

switch coordinates {
case (0, 0, 0):
  print("Origin")
case (let x, 0, 0):
  print("On the x-axis at x = \(x)")
case (0, let y, 0):
  print("On the y-axis at y = \(y)")
case (0, 0, let z):
  print("On the z-axis at z = \(z)")
case let (x, y, z):
  print("Somewhere in space at x = \(x), y = \(y), z = \(z)")
}

使用let语法来提取相关值。然后使用字符串插值打印出来。

switch语句中没有default选项。因为已经穷举了所有情况,所以不用写默认值。

注:想提取元组的所有值时,let (x, y, z)(let x, let y, let z)一样。

最后,可以使用let-where语法来匹配更复杂的情况:

switch coordinates {
case let (x, y, _) where y == x:
  print("Along the y = x line.")
case let (x, y, _) where y == x * x:
  print("Along the y = x^2 line.")
default:
  break
}

你可能感兴趣的:(IOS迷你教程3-Swift语言之流程控制(swift4.2))