Swift-21-程序逻辑控制

swift语言的逻辑控制比一般的语言要复杂的多,它在原有的if, while基本上又增加了很多新功能。这些需要仔细研究下

循环结构

在switf中有两种循环:for和while

for 循环

for...in

swift 复制代码
//简单示例,正常打印5次
var myFirstInt = 0
for i in 1...5 { //正常写法是 for i: Int in 1...5
    print(myFirstInt + i)
} //~~ 1, 2, 3, 4, 5

//也可写成这样,用_通配符代替,但这样就取不到每次迭代的值了
for _ in 1...5 {
    print(myFirstInt)
}

where子句

swift 复制代码
//where子句,相当于对每次特殊的值加了一个筛选条件。下例表示:从100个数中取得能整除3的数字
for i in 1...100 where i % 3 == 0 {
    print(i)
}

while循环

while...do

swift 复制代码
// while...do写法
var i = 1
while i < 6 {
    print(i)
    i += 1
}

repeat...while(do...while)

在其它语言中称为do...while,即先执行一次再看是否再次执行;

swift 复制代码
var shields = -1;
repeat {
    print("Fire blasters!")
} while shields > 0

break和continue

  • break:跳出当前整体循环;
  • continue:跳过本次循环从头开始,和其它语言的continue意思一样;

一个稍复杂的例子

swift 复制代码
var shields = 5 //护盾强度
var blastersOverheating = false //武器是否需要冷却
var blasterFireCount = 0 //武器开火次数
var spaceDemonsDestroyed = 0 //击杀怪物的总数量
while shields > 0 {
    if spaceDemonsDestroyed == 5 {
        print("You beat the game!")
        break
    }
    print(blastersOverheating);
    //检查武器是否过热
    if blastersOverheating {
        print("Blasters are overheated!  Cooldown initiated.")
        blastersOverheating = false
        blasterFireCount = 0
        continue //从这就打断了循环,从头开始了
    }
    
    //检查开火次数,达到一定3次时,要设置标志位冷却下武器
    if blasterFireCount > 2 {
        blastersOverheating = true
        continue //从这就打断了循环,从头开始了
    }
    
    print("Fire blasters!")
    blasterFireCount += 1
    spaceDemonsDestroyed += 1
}
/*
    Fire blasters!
    Fire blasters!
    Fire blasters!
    Blasters are overheated!  Cooldown initiated.
    Fire blasters!
    Fire blasters!
    You beat the game!
 */

以上语句都可以混合break和continue一起使用。

选择结构

if 选择

if...else

语法关键字:if、 else以及 else if。

swift 复制代码
    var message: String
    var hasPostOffice: Bool = true
    
    if (population < 10000) {
        message = "\(population) is a small town!"
    } else if (population >= 10000 && population < 50000) {
        message = "\(population) is a medium town!"
    } else {
        message = "\(population) is pretty big!"
    }

if case

这种写法完全可以用if...else或switch来代替,属于一个中间品,也是swift语言等有的,用处不大,了解下即可。

swift 复制代码
let age = 25
if case 18...35 = age {
    print("Cool demographic")
}

if case 18...35 = age, age >= 21 {
    print("In cool demographic and of drinking age")
}

//~~ Cool demographic
//~~ In cool demographic and of drinking age

guard(if返例)

与if语句相同的是,guard也是基于一个表达式的布尔值去判断一段代码是否该被执行。与if语句不同的是,guard只有在条件不满足的时候才会执行这段代码。你可以把guard近似的看做是Assert,但是你可以优雅的退出而非崩溃。其语法结构如下:

swift 复制代码
guard expression else { 
    //语句
    //必须包含一个控制语句:return,break,continue或throw。
}
  • 如果对表达式求值false,guard则执行代码块内的语句。
  • 如果对表达式求值true,guard则从执行中跳过代码块内的语句
swift 复制代码
guard let username = usernameTextField.text, !username.isEmpty else {
    show("用户名不能为空")
    return
}
guard let password = passwordTextField.text, !password.isEmpty else {
    show("密码不能为空")
    return
}
register(username, password)

switch 选择

可以接受整型和枚举,先看一个简单的例子

swift 复制代码
var statusCode: Int = 420
var errorString: String = "The request failed:"

switch statusCode {
    case 400:
       errorString += "bad Request, \(statusCode)."
    case 500:
       errorString += "server error, \(statusCode)."
    default:
        errorString += "unknown, \(statusCode)."
}
print(errorString) //~~The request failed:unknown, 420.

case组合

如果多个错误码对应同一个错误信息时,可以像下面这样来写

swift 复制代码
var statusCode: Int = 520
var errorString: String = "The request failed:"

switch statusCode {
    case 400:
       errorString += "bad Request, \(statusCode)."
    case 500, 510, 520, 530:
       errorString += "server error, \(statusCode)."
    default:
        errorString += "unknown, \(statusCode)."
}
print(errorString) //~~The request failed:server error, 520.

case区间

上面采用罗列的方式是比原始简单了一些,但如果有上百个值的话,那么写起来也是很费劲的,所以switch又提供了区间的功能,其格式为:

  • intStart...intEnd:如300...600,表示300到600间所有的整数;
swift 复制代码
var statusCode: Int = 520
switch statusCode {
    case 400:
       errorString += "bad Request, \(statusCode)."
    case 500, 510, 520, 530:
       errorString += "server error, \(statusCode)."
    case 600...800:
       errorString += "nginx error, \(statusCode)."
    default:
        errorString += "you must fix it."
}
print(errorString) //~~The request failed:server error, 520.

fallthrough

在switch的switch语句中不需要使用break语句,都是隐式设置的。另外它又新增了一个叫fallthrough的关键字,不太好解释其作用,直接看例子可能更直观。

swift 复制代码
var statusCode: Int = 520
switch statusCode {
    case 400:
       errorString += "bad Request, \(statusCode)."
    case 500, 510, 520, 530:
       errorString += "server error, \(statusCode)."
       fallthrough
    default:
        errorString += "you must fix it."
}
print(errorString) //~~The request failed:server error, 520.you must fix it.

另外一个例子

swift 复制代码
var statusCode: Int = 520
var errorString: String = "The request failed:"

switch statusCode {
    case 400:
       errorString += "bad Request, \(statusCode)."
    case 500, 510, 520, 530:
       errorString += "server error, \(statusCode)."
       fallthrough
    case 600:
       errorString += "server error, \(statusCode)."
    default:
        errorString += "you must fix it."
}
print(errorString) //~~The request failed:server error, 520. server error, 520.

仔细查看以上代码输出:

  • break:默认会加在每个case代码块的最末尾,如果匹配就跳出整个switch语句;
  • fallthrough:它会无条件执行它下一个case语句,无论是否匹配上;

swift中的switch比其它语言要复杂一点,它可以动态运算。正常case的值可接受String、Int类型的数字以及Enum枚举全可以,需要注意的是在case语句默认带了break

(也可以显式的写break),如果想用continue,则需要用关键字fallthrough来代替。标准写法格式如下面代码所示:

swift 复制代码
var statusCode: Int = 420
var errorString: String = "The request failed:"
switch statusCode {
//多case值
case 100, 101:
    errorString += " Informational, \(statusCode)." //statusCode是一个变量引用
    
case 204:
    errorString += " Successful but no content, \(statusCode)."
    fallthrough //代替了continue
default:
    errorString = "Unknown error encountered."
    break  //可以省略
}

值绑定

值绑定能在某个特定分支中把待匹配的值绑定(bind)到本地的常量或变量上。这个常量或变量只能在该分支中使用。可以用var或let来定义。

swift 复制代码
var statusCode: Int = 900
var errorString: String = "The request failed:"
switch statusCode {
case 100, 101:
    errorString += " Informational, \(statusCode)."
    
case 300...307:
    errorString += " Redirection, \(statusCode)."
    
case 400...417:
    errorString += " Client error, \(statusCode)."

case let unknownCode:
    errorString = "\(unknownCode) Unknown error encountered."

default :
    errorString = "Unknown error encountered." //不会执行    
}   
print(errorString) //~~900 Unknown error encountered.

这里的unknownCode虽然没有初始化,但默认它的值就是前面swith的值(statusCode),在这个例子中此值为900;所以打印出的结果为"900 Unknown error encountered."。

上述这种写法可以代替default语句。如果同时存在default语句,又如果都能匹配上case,则default不会执行。

where子句

where子句其实就是对值绑定语句的一次细化,表示从已匹配的值中再刨除掉一部分值。

swift 复制代码
var statusCode: Int = 620
var errorString: String = "The request failed:"
switch statusCode {
case 100, 101:
    errorString += " Informational, \(statusCode)."
    
case 204:
    errorString += " Successful but no content, \(statusCode)."
    
case 300...307:
    errorString += " Redirection, \(statusCode)."
    
//匹配除了前面三个case值外,如果程序运行到这里了,则只匹配:200~300或大于505的值
case let unknownCode where (unknownCode >= 200 && unknownCode < 300) || unknownCode > 505:
    errorString = "\(unknownCode) is not a known error code."
    
default:
    errorString = "Unknown error encountered."
}
print(errorString)
//~~statusCode=620时,620 is not a known error code.
//~~statusCode=420时,Unknown error encountered.

元组匹配

正常来讲case只是一个值,在swift中可以指定多个值。在实际中适用于逻辑关联有两个或多个值的情况,其实这种便利也可以用一步计算得出,然后再在switch中匹配计算出来的值。

Swift 复制代码
let firstErrorCode = 404
let secondErrorCode = 200
let errorCodes = (firstErrorCode, secondErrorCode)

switch errorCodes {
case (404, 404):
    print("No items found.")
case (404, _):     // _ 表示匹配任意值
    print("First item not found.")
case (_, 404):
    print("Second item not found.")
default:
    print("All items found.")
}

//~~First item not found.

元组操作

swift 复制代码
//不带名称的元组
let firstErrorCode = 404
let secondErrorCode = 200
let errorCodes = (firstErrorCode, secondErrorCode)
print(errorCodes.0)
print(errorCodes.1)

//带名称的元组
let firstErrorCode = 404
let secondErrorCode = 200
let errorCodes = (first: firstErrorCode, second: secondErrorCode)
print(errorCodes.first)
print(errorCodes.second)

运算符

  1. 四则运算: +、 -、 *、 \、 %、++、--
  2. -(负号)
  3. 赋值运算:=、+=、-=、/=、*=
  4. 三元运算符:condition ? expression1: expression2
  5. 位运算:&、 |、 ^、 ~(求反)、 << 、>>
  6. 关系运算:==、!=、< 、 > 、 <= 、 >=
  7. 引用运算:=、! 计算两个实例是否指向同一个引用
  8. 溢出运算:&+、 &-、 &*、 &\(不太建议使用)
  9. 可空类型运算:??
相关推荐
什么鬼昵称6 分钟前
Pikachu- Over Permission-垂直越权
运维·服务器
码农小白18 分钟前
linux驱动:(22)中断节点和中断函数
linux·运维·服务器
2401_857610031 小时前
SpringBoot实现:校园资料分享平台开发指南
服务器·spring boot·php
C++忠实粉丝2 小时前
Linux环境基础开发工具使用(2)
linux·运维·服务器
康熙38bdc2 小时前
Linux 环境变量
linux·运维·服务器
存储服务专家StorageExpert2 小时前
DELL SC compellent存储的四种访问方式
运维·服务器·存储维护·emc存储
GEEKVIP2 小时前
手机使用技巧:8 个 Android 锁屏移除工具 [解锁 Android]
android·macos·ios·智能手机·电脑·手机·iphone
GEEKVIP2 小时前
如何在 Windows 10 上恢复未保存/删除的 Word 文档
macos·ios·智能手机·电脑·word·笔记本电脑·iphone
奇客软件3 小时前
iPhone使用技巧:如何恢复变砖的 iPhone 或 iPad
数码相机·macos·ios·电脑·笔记本电脑·iphone·ipad
长天一色3 小时前
【ECMAScript 从入门到进阶教程】第三部分:高级主题(高级函数与范式,元编程,正则表达式,性能优化)
服务器·开发语言·前端·javascript·性能优化·ecmascript