美文网首页iOS开发iOS迷你教程
IOS迷你教程3-Swift语言之流程控制(swift4.2)

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

作者: Lebus | 来源:发表于2018-10-15 22:24 被阅读87次

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

    在本教程中,您将学习如何来控制流程,从而让计算机听你的话。您还将了解布尔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

    (<CONDITION>) ? <TRUE VALUE> : <FALSE VALUE>
    

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

    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 <CONDITION> {
      <LOOP CODE>
    }
    

    每一次循环,都会先检查条件。如果条件是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 {
      <LOOP CODE>
    } while <CONDITION>
    

    这是上一节的示例,使用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 <CONSTANT> in <RANGE> {
      <LOOP CODE>
    }
    

    循环以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..<count {
      let temp = sum
      sum = sum + lastSum
      lastSum = temp
    }
    

    只是单纯的想让代码执行一定的次数,不需要用到循环常量(上述i)。
    0..<count半开,表示代码将执行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)

        本文链接:https://www.haomeiwen.com/subject/hklqzftx.html