Swift系列二 - 循环控制

一、if-else

  • if后面的条件可以省略小括号
  • 条件后面的大括号不可以省略
let age = 10
if age >= 18 {
    print("大学")
} else if age >= 16 {
    print("高中")
} else {
    print("义务")
}
  • if后面的条件只能是Bool类型


    image

二、while

var num = 3
while num > 0 {
    print("num is \(num)")
    num -= 1
}
/*
 输出:
 num is 3
 num is 2
 num is 1
 */
  • swift中没有do-while,相同逻辑的是repeat-while
  • swift3开始,去除了自增(++),自减(--)运算符
    • 不要再使用num++num--++num--num等运算符了
    • 自增自减运算符在不同平台有不一样的效果,所以swift放弃了使用
var num = -1
repeat {
    print("num is \(num)")
} while num > 0
/*
 输出:num is -1
 */

三、for

3.1. 区间运算符

格式:a...b(a <= 取值 <= b)

  • 变量默认是let修饰,可以自己根据情况修改为var
// 常规用法
let words = ["aaa", "bbb", "ccc", "ddd"]
for i in words {
    print(i);
}
/*
 输出:
 aaa
 bbb
 ccc
 ddd
 */

// 区间用法
for i in 1...3 {
    print(i, words[i])
}
/*
 输出:
 1 bbb
 2 ccc
 3 ddd
 */

// var修饰
for var i in 1...3 {
    i += 5
    print(i)
}
/*
 输出:
 6
 7
 8
 */

// 区间定义常量
let range = 1...3
for i in range {
    print(i)
}
/*
 输出:
 1
 2
 3
 */

// 区间值自定义
let a = 1
let b = 3
for i in a...b {
    print(i)
}
/*
 输出:
 1
 2
 3
 */

3.2. 半开区间运算符

格式:a..<b(a <= 取值 < b)

for i in 1..<3 {
    print(i)
}
/*
 输出:
 1
 2
 */

3.3. 区间运算符用在数组上

// 此处只是示例用法,实际应用时应注意数组越界
let words = ["aaa", "bbb", "ccc", "ddd"]
for i in words[0...3] {
    print(i);
}

3.4 单侧区间:让区间朝一个方向尽可能的远

// 常规闭区间
let words = ["aaa", "bbb", "ccc", "ddd"]
for word in words[0...3] {
//    print(word);
}
/*
 输出:
 aaa
 bbb
 ccc
 ddd
 */

// 左边代表开始,右边代表数组最大长度
for word in words[2...] {
    print(word)
}
/*
 输出:
 ccc
 ddd
 */

// 左边代表0,右边闭区间值
for word in words[...2] {
    print(word)
}
/*
 输出:
 aaa
 bbb
 ccc
 */

// 左边代表0,右边<2
for word in words[..<2] {
    print(word)
}
/*
 输出:
 aaa
 bbb
 */

// 无限制,range左边是无穷小的整数
let range = ...5
print(range.contains(7)) // false
print(range.contains(1)) // true
print(range.contains(-2)) // true

四、区间类型(Range)

  • 范围代表的是两个值的区间,它由上下边界进行定义;
  • 不能对 Range 或者 ClosedRange 进行迭代,但是我们可以检查某个元素是否存在于范围中;
  • Range 和 ClosedRange 既非序列,也不是集合类型。有一部分范围确实是序列是因为 0..<10 的类型其实是一个 CountableRang。CountableRange 和 Range 很相似,只不过它还需要一个附加约束:它的元素类型需要遵守 Strideable 协议 (以整数为步⻓)。Swift 将这类功能更强的范围叫做可数范围,这是因为只有这 类范围可以被迭代。可数范围的边界可以是整数或者指针类型,但不能是浮点数类型,这是由 于 Stride 类型中有一个整数的约束。如果你想要对连续的浮点数值进行迭代的话,你可以通过 使用 stride(from:to:by) 和 stride(from:through:by) 方法来创建序列用以迭代。
-- 半开 闭合
Comparable Range ClosedRange
Strideable(以整数为步长) CountableRange CountableClosedRange

4.1. 同时省略掉上、下两个边界,这样你将会得到整个集合类型的切片

let arr = [1,2,3,4]
arr[...] // [1, 2, 3, 4] 
type(of: arr) // Array<Int>
// 半开区间
let rang: Range = 0.0..<1.0
let countableRange: CountableRange = 0..<1

// 闭区间
let closedRange: ClosedRange = 0.0...1.0 
let countableClosedRange: CountableClosedRange = 0...1 

// 右侧闭区间
let partialRangeThrough: PartialRangeThrough = ...1.0
// 左侧闭区间
let partialRangeFrom: PartialRangeFrom = 0.0...
// 右侧开区间
let partialRangeUpTo: PartialRangeUpTo = ..<1.0
// 左侧闭区间
let countablePartialRangeFrom: CountablePartialRangeFrom  = 1...

4.2. 字符、字符串也能使用区间运算符,但默认不能用在for-in中

let stringRange1 = "cc"..."ff"
stringRange1.contains("cb") // false
stringRange1.contains("dz") // true
stringRange1.contains("e") // true
stringRange1.contains("fg") // false

let stringRange2 = "a"..."f"
stringRange2.contains("a") // true
stringRange2.contains("e") // true
stringRange2.contains("g") // false

// \0到~囊括了所有可能要用到的ASCII字符
let characterRange: ClosedRange<Character> = "\0"..."~"
characterRange.contains("G") // true

4.3 带间隔的区间值

let startValue = 0
let endValue = 10
let interval = 2
// value取值从startValue开始,每次间隔interval,不超过endValue
for value in stride(from: startValue, through: endValue, by: interval) {
    print(value)
}
/*
 输出:
 0
 2
 4
 6
 8
 10
 */

 // 另外一个方法 to是开区间
 public func stride<T>(from start: T, to end: T, by stride: T.Stride) -> StrideTo<T> where T : Strideable

五、switch

5.1. case、default后面不能写大括号(编译器会报错)

5.2. 默认情况下可以不写break,并不会贯穿到后面的条件

enum HeaderCode {case success, failure, redirect, connect}
let code = HeaderCode.success
switch code {
case .success:
    print("success")
case .redirect:
    print("redirect")
case .connect:
    print("connect")
default:
    print("failure")
}
/*
 输出:success
 */

5.3. 如果需要贯穿,怎么办?fallthrough

enum HeaderCode {case success, failure, redirect, connect}
let code = HeaderCode.success
switch code {
case .success:
    print("success")
    fallthrough
case .redirect:
    print("redirect")
case .connect:
    print("connect")
default:
    print("failure")
}
/*
 输出:
 success
 redirect
 */

5.4. case、default后面至少要有一条语句

image

5.5. switch必须要保证能处理所有情况

  • 如果不想做任何事,加个break即可
  • 如果能保证已处理所有情况,也可以不使用default
enum HeaderCode {case success, failure, redirect, connect}
let code = HeaderCode.success
switch code {
case .success:
    break
case .redirect:
    print("redirect")
case .connect:
    print("connect")
case .failure:
    print("failure")
}

5.6. 复合条件(switch支持Character、String类型)

// String
let string = "idbeny"
switch string {
case "idbeny":
    print("idbeny")
    fallthrough
case "developer":
    print("developer")
default:
    print("man")
}
/*
 输出:
 idbeny
 developer
 */

// Character
let character: Character = "a"
switch character {
case "a", "A":
    print("aaa")
default:
    print("not found")
}
/*
 输出:aaa
 */

5.7. 区间匹配、元组匹配

// 区间匹配
let count = 10
switch count {
case 0:
    print("zero")
case 1...5:
    print("few")
case 10...100:
    print("large")
default:
    print("not found")
}
/*
 输出:large
 */

// 元组匹配
let point = (1, 1)
switch point {
case (0, 0):
    print("origin")
case (_, 0):
    print("x-axis")
case (0, _):
    print("y-axis")
case (-2...2, -2...2):
    print("in the box")
default:
    print("not found")
}
/*
 输出:in the box
 */
  • 可以用下划线(_)忽略某个值
  • 值绑定(必要时let可以改为var)
let point1 = (2, 0)
switch point1 {
case (let x, 0):
    print("on the x-axis and x value of \(x)")
case (0, let y):
    print("on the y-axis and y value of \(y)")
case (let x, let y):
    print("at (\(x), \(y))")
}
/*
 输出:on the x-axis and x value of 2
 */

六、where(过滤)

let point = (1, -1)
switch point {
case let(x, y) where x == y:
    print("x == y")
case let(x, y) where x == -y:
    print("x == -y")
case let(x, y):
    print("at (\(x), \(y))")
}
/*
 输出:x == -y
 */

// 把所有数加起来
var numbers = [10, 20, -30, -40, 50]
var sum = 0
for num in numbers where num > 0 {
    sum += num
}
print(sum)
/*
 输出:80
 */

七、标签语句

side: for i in 1...4 {
    for k in 1...4 {
        if k == 3 {
            continue side
        }
        if i == 3 {
            break side
        }
        print("i == \(i), k == \(k)")
    }
}
/*
 输出:
 i == 1, k == 1
 i == 1, k == 2
 i == 2, k == 1
 i == 2, k == 2
 */
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,835评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,598评论 1 295
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,569评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,159评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,533评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,710评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,923评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,674评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,421评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,622评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,115评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,428评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,114评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,097评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,875评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,753评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,649评论 2 271

推荐阅读更多精彩内容