美文网首页
#5 流程控制

#5 流程控制

作者: JamesSawyer | 来源:发表于2018-08-22 23:52 被阅读17次

swift中主要使用下面几种控制流程:

  • for-in: 对集合进行遍历
  • while|repeat-while: 和其它语言的一样,repeat-while 就是其它语言中的 do-while语句
  • if-else if -else: 条件判断语句,可以在if中顺便声明一下变量什么的,其它没什么可讲的
  • switch: 这个感觉在swift中功能很强大,可以配合 where 对条件进一步过滤,详讲
  • guard-else: 这个就是 if 语句的另一种表示方式,但是其更加的语义化,是控制流程更加的清晰
  • if #available(platform name version, ..., *): 检测API可用性

switch

swift中的switch和OC,C,JS不同之处在于,其遇到满足的分支即退出流程,不会再继续,因此 swift中 break不是必须的

// js 中
const name = 'james'
switch (name) {
  case 'james':
    console.log('his name is james');
  default:
    console.log('his name is unknown');
}

// 打印
// his name is james
// his name is unknown

// 更正
const name = 'james'
switch (name) {
  case 'james':
    console.log('his name is james');
    break; // 使用break退出流程
  default:
    console.log('his name is unknown');
}
// 打印
// his name is james

swift中

// swift 中
let name = "james"
switch name {
  case "james":
    print("his name is james");
  default:
    console.log("his name is unknown");
}
// 打印
// his name is james

可以同时匹配多个

JS中匹配多个条件一般使用多个case放在一起的方式,但是swift中一般不这样做,直接使用 , 分割即可

// js
const char = 'a'
switch (char) {
    // 多个case语句放在一起
  case 'A':
  case 'a':
      console.log('the character is a');
        break;
  default:
      console.log('character is not a');
}
// the character is a

swift中:

let char: Character = "a"
switch char {
  case "a", "A":
    print("the character is a")
  default:
    print("character is not a")
}
// the character is a

区间匹配

这个比较屌

// swift
let count = 12
let countedThings = "moons orbiting Saturn"
var naturalCount: String

switch count {
  case 0:
    naturalCount = "no"
  // 使用 1..<5 产生一个Range
  case 1..<5:
    naturalCount = "a few"
  case 5..<12:
    naturalCount = "serval"
  case 12..<100:
    naturalCount = "dozens of"
  default:
    naturalCount = "many"
}
print("there are \(naturalCount) \(countedThings)")

//  "There are dozens of moons orbiting Saturn"

元组

使用元组在同一个switch语句中测试多个值。元组中的元素可以使值,也可以是区间,使用下划线(_)来匹配所有可能的值

// (Int, Int)类型的元组分类图中的点(x, y)
let somePoint = (1, 1)
switch somePoint {
case (0, 0):
  print("\(somePoint) 在原点")
case (_, 0):
  print("\(somePoint) 在x轴上")
case (0, _):
  print("\(somePoint) 在y轴上")
case (-2...2, -2...2):
  print("\(somePoint) 在这个区间围成的盒子里面")
default:
  print("\(somePoint) 在盒子外面")
}
// (1, 1) 在这个区间围成的盒子里面

值绑定

case 分支允许将匹配的值什么为临时常量或者变量,并且在case分支中使用,这种行为称之为值绑定

// (Int, Int)类型的元组分类图中的点(x, y)
let somePoint = (2, 0)
switch somePoint {
case (let x, 0):
  // 上面声明的临时常量可以在case语句中使用
  print("\(somePoint) 在x轴上, x的值为 \(x)")
case (0, let y):
  print("\(somePoint) 在y轴上, y的值为 \(y)")
case let (x, y):
  print("\(somePoint) 在(\(x), \(y))位置")
}
// (2, 0) 在x轴上, x的值为2

case 中配合 where 语句

where 语句可以添加额外的判断:

let somePoint = (1, -1)
switch somePoint {
case let (x, y) where x == y:
  print("(\(x), \(y)) 在 x == y 这条直线上")
case let (x, y) where x == -y:
  print("(\(x), \(y)) 在 x == -y 这条直线上")
case let (x, y):
  print("(\(x), \(y)) 是任意的一个点")
}
// (1, -1) 在 x == -y 这条直线上

复合匹配同样可以包含值绑定。复合匹配里所有的匹配模式,都必须包含相同的值绑定。并且每一个绑定都必须获取到相同类型的值。这保证了,无论复合匹配中的哪个模式发生了匹配,分支体内的代码,都能获取到绑定的值,并且绑定的值都有一样的类型

// (let distance, 0) 匹配在x轴上的值
// (0, let distance) 匹配在y轴上的值
// 2个模式都绑定了 distance
// 并且 distance 在2种模式下,都是整型
// 这意味着分子体内的代码,只要case匹配,都可以获取到distance值
let somePoint = (9, 0)
switch somePoint {
case (let distance, 0), (0, distance):
  print("点在轴上, 距离原点位置为 \(distance)")
default:
  print("不在轴上")
}

switch 中控制转移语句

改变代码执行顺序,实现代码跳转,swift有5种控制转移语句:

  • continue
  • break
  • fallthrough
  • return
  • throw

continue

这个其实和其它语言中的一样, 即停止本次循环,开始下一次循环

let puzzleInput = "great minds think alike"
var puzzleOutput = ""
for char in puzzleInput {
  switch char {
  case "a", "e", "i", "u", "o", " ":
    // 碰到元音或者空格则进入下一次循环
    continue
  default:
    puzzleOutput.append(char)
  }
}
print(puzzleOutput) // "grtmndsthnklk"

break

会立即结束整个控制流的执行。因为swift的switch需要包含所有的分支而且不允许有为空的分支,有时为了使意图更明显,需要特意匹配或者忽略某个分支

let numberSymbol: Character = "三"  // 简体中文里的数字 3
let numberSymbol: Character = "三"  // 简体中文里的数字 3
var possibleIntegerValue: Int?
switch numberSymbol {
case "1", "١", "一", "๑":
    possibleIntegerValue = 1
case "2", "٢", "二", "๒":
    possibleIntegerValue = 2
case "3", "٣", "三", "๓":
    possibleIntegerValue = 3
case "4", "٤", "四", "๔":
    possibleIntegerValue = 4
default:
    break
}
if let integerValue = possibleIntegerValue {
    print("The integer value of \(numberSymbol) is \(integerValue).")
} else {
    print("An integer value could not be found for \(numberSymbol).")
}
// 输出 "The integer value of 三 is 3."

fallthrough

swift中,switch语句不会从上一个case分支跳到下一个case分支中。相反,只要匹配到case分支,就结束了。其它语言需要插入 break 结束,是贯穿的,如果想要这种贯穿的特性,swift中使用 fallthrough 关键词

let integerToDescribe = 5
switch integerToDescribe {
case 2, 3, 5, 7, 11, 13, 17, 19:
    description += " a prime number, and also"
    // 满足这个条件之后 会继续到下一个分支
    fallthrough
default:
    description += " an integer."
}
print(description)
// 输出 "The number 5 is a prime number, and also an integer."

guard else 语句

guard 的执行取决于一个表达式的布尔值。

  • 我们可以使用 guard 语句来要求条件必须为真,以执行 guard 语句后的代码。
  • 一个 guard 语句总是有一个 else 从句,如果条件不为真,则执行 else 从句中的代码
  • else 从句必须转移控制,以退出 guard 语句出现的代码段,可以使用 return | break | continue | throw 或者调用一二不返回的方法或函数,比如 fatalError() 进行退出
func greet(_ person: [String: String]) {
  guard let name = person["name"] else {
    // 如果person字典中没有 "name" key 就直接退出
    return
  }
  // 如果有 "name" key 则继续执行下面内容
  print("hello \(name)")
  
  guard let location = person["location"] else {
    print("I hope the weather is nice near you.")
    return
  }
  print("I hope the weather is nice in \(location).")
}
greet(["name": "John"])
// 输出 "Hello John!"
// 输出 "I hope the weather is nice near you."
greet(["name": "Jane", "location": "Cupertino"])
// 输出 "Hello Jane!"
// 输出 "I hope the weather is nice in Cupertino."

上面代码其实等价于:

func greet(_ person: [String: String]) {
  if let name = person["name"] {
    print("hello \(name)")
  } else {
    return
  }

  if let location = person["location"] {
    print("I hope the weather is nice in \(location).")
  } else {
    print("I hope the weather is nice near you.")
    return
  }
}

检测 API 可用性

这可以确保我们不会再当前部署机器上,不小心地使用了不可用的API

// 还可以指定小版本号 比如 iOS 11.2.6, macOS 10.13.3
if #available(iOS 10, macOS 10.12, *) {
    // 在 iOS 使用 iOS 10 的 API, 在 macOS 使用 macOS 10.12 的 API
} else {
    // 使用先前版本的 iOS 和 macOS 的 API
}

其语法为:

// platform name 是下列值: iOS,macOS,watchOS 和 tvOS
// * : 是必须要带上的参数,用于指定在所有其它平台中,如果版本号
// 高于你的设备指定的最低版本,if语句的代码将运行
if #available(platform name version, ..., *) {
  APIs 可用,语句将执行
} else {
  APIs 不可用,语句将不执行
}

相关文章

  • #5 流程控制

    control flow swift中主要使用下面几种控制流程: for-in: 对集合进行遍历 while|re...

  • Swift5 基础教程与进阶合集

    Swift5 基础 Swift5 基础(一)Swift编译流程、基础语法、流程控制、函数、枚举[https://w...

  • Swift5复习(一)Swift编译流程、基础语法、流程控制、函

    Swift5复习(一)Swift编译流程、基础语法、流程控制、函数、枚举Swift5复习(二)可选项、结构体、类、...

  • Swift5复习(四)继承、初始化、可选链

    Swift5复习(一)Swift编译流程、基础语法、流程控制、函数、枚举Swift5复习(二)可选项、结构体、类、...

  • Swift5复习(三)属性、方法、下标

    Swift5复习(一)Swift编译流程、基础语法、流程控制、函数、枚举Swift5复习(二)可选项、结构体、类、...

  • 5-流程控制

    流程控制 流程 计算机执行代码的顺序就是流程 流程控制 对计算机代码执行顺序的管理就是流程控制 流程分类 流程控制...

  • 04-流程控制及while循环

    流程控制 流程: 计算机执行代码的顺序,就是流程。 流程控制: 对计算机代码执行顺序的控制,就是流程控制。 流程分...

  • 5. 流程控制

    if 如果 if 或 elseif 有一个满足条件,则不继续进行判断。 在第一种方式中,else if可以写成el...

  • 5.流程控制

    流程控制 请列出3种PHP数组循环操作的语法,并注明各种循环的区别? for循环 foreach循环 while ...

  • JavaScript-流程控制语句

    一、if流程控制语句 二、switch流程控制语句 三、流程控制语句

网友评论

      本文标题:#5 流程控制

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