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. 可空类型运算:??
相关推荐
pe7er2 天前
macOS 应用无法打开(权限问题)解决方案
macos·mac
iOS日常2 天前
iOS设备崩溃日志获取与查看
ios·xcode
Sinclair2 天前
简单几步,安卓手机秒变服务器,安装 CMS 程序
android·服务器
iOS日常3 天前
Xcode 垃圾清理
ios·xcode
Rockbean3 天前
用40行代码搭建自己的无服务器OCR
服务器·python·deepseek
埃博拉酱3 天前
VS Code Remote SSH 连接 Windows 服务器卡在"下载 VS Code 服务器":prcdn DNS 解析失败的诊断与 BITS 断点续传
windows·ssh·visual studio code
茶杯梦轩3 天前
CompletableFuture 在 项目实战 中 创建异步任务 的核心优势及使用场景
服务器·后端·面试
海天鹰4 天前
【免费】PHP主机=域名+解析+主机
服务器
不是二师兄的八戒4 天前
Linux服务器挂载OSS存储的完整实践指南
linux·运维·服务器
芝士雪豹只抽瑞克五4 天前
Nginx 高性能Web服务器笔记
服务器·nginx