一个下午让你掌握Swift基础 ( 5/9 ) 做判断

作者: 张嘉夫 | 来源:发表于2016-07-05 14:58 被阅读626次

    简介

    这是一个Swift语言教程,基于最新的iOS 9,Xcode 7.3和Swift 2.2,会为你介绍Swift编程非常基础的内容。从电脑如何工作的全程基本原理到语言结构,你会足够了解这门语言,来处理数据和管理代码的行为。

    快速链接


    做判断

    写一个电脑程序的时候,需要能够用不同的剧本告诉电脑该干什么。例如,一个计算器app在用户按加号按钮的时候要做一件事,按减号按钮的时候做另一件事。
    在电脑编程领域,这个概念被称作控制流(control flow)。它被这样命名因为程序的流程(flow)由多种方法控制。在这篇文章里,你会学习到在程序里如何做判断,以及通过使用语法来控制流程。

    if语句

    第一个也是最常用的控制程序流程的方式就是使用if语句(if statement),可以让程序只在某个特定情况是true的时候做一些事。例如,看下面的代码:

    if 2 > 1 {
        print("是的,2比1大。")
    }
    

    这一个简单的if语句。如果括号里的情况是true,语句就会执行花括号里的代码。如果括号里的情况是false,语句不会执行花括号里的代码。就这么简单!

    上面的代码也为你介绍了新语法:print()函数,简单地显示一些东西到屏幕上。在你的playground里,你可以看见上面print()语句的结果,通过点击 View\Debug Area\Show Debug Area

    你会看见这样的东西:

    点击上面截图上高亮的两个按钮也可以显示debug(排除错误)区域。Xcode有很多方式来完成同样的事情!

    你可以扩展一个if语句,提供在情况是false的时候运行的代码。这被称作else子句(clause)。这是一个例子:

    let animal = "狐狸"
    
    if animal == "猫" || animal == "狗" {
        print("这个动物是居家宠物。")
    } else {
        print("这个动物不是居家宠物。")
    }
    

    这里,如果(if)animal等于“猫”或“狗”,然后语句会运行代码的第一块。如果animal既不等于“猫”又不等于“狗”,语句会运行if语句里else里的那部分代码,在debug区域显示如下内容:

    这个动物不是居家宠物。
    

    其实使用 if 语句还能做更多事情。有时候你想检测一个情况,然后是另一个情况。这就是else-if语句参演的地方啦。
    你可以像这样使用:

    let hourOfDay = 12
    let timeOfDay: String
    if hourOfDay < 6 {
        timeOfDay = "清晨"
    } else if hourOfDay < 12 {
        timeOfDay = "上午"
    } else if hourOfDay < 17 {
        timeOfDay = "下午"
    } else if hourOfDay < 20 {
        timeOfDay = "晚上"
    } else if hourOfDay < 24 {
        timeOfDay = "夜深了"
    } else {
        timeOfDay = "这他妈不是时间!"
    }
    print(timeOfDay)
    

    一个接一个的else-if语句来测试多种情况,直到发现一个true情况。它只会执行和第一个true情况相关的代码,无论随后的else-if情况是不是true。换句话说,else-if情况的顺序影响很大!

    你可以在末尾加一个else,来处理所有都不是true的情况。else是可选的,如果你不需要它那就不要;在这个例子里你的确需要它,来确保timeOfDay在你输出它的时候有一个有效值。

    这个例子里,else-if语句带有一个数字,表示一天中的时间,然后把它转换到一个字符串,表示这个小时属于一天中的哪个部分。采用24小时时间制,语句被按顺序一个一个检查:

    • 第一次检查看看小时是不是小于6。如果是,意味着在清晨。
    • 如果小时不小于6,语句继续执行第一个else-if,检查小时是不是小于12。
    • 然后按顺序,在情况是false的时候,语句检查小时是不是小于17,然后是小于20,然后是小于24。
    • 最后,如果小时数超出范围了,语句察觉到了一个无效情况,然后把这个信息打印到了控制台。

    在上面的代码里,hourOfDay常量是12。因此,代码会在屏幕上像下面这样显示:

    下午
    

    注意即使hourOfDay < 20和hourOfDay < 24情况也都是true,但语句只执行了输入满足的第一个else-if,当然就是hourOfDay < 17情况啦。

    包含变量

    If 语句介绍了一个新概念,那就是scope(范围),通过使用花括号来包含变量的一种方式。

    让我们看一个例子。想象一下你要计算向顾客收取的费用。

    这是你打好的算盘:

    你每小时赚25块,最多40小时,此后的每小时都要50块。

    使用Swift,你可以这样计算你的费用:

    var hoursWorked = 45
    
    var price = 0
    if hoursWorked > 40 {
      let hoursOver40 = hoursWorked - 40
      price += hoursOver40 * 50
      hoursWorked -= hoursOver40
    }
    price += hoursWorked * 25
    
    print(price)
    

    这段代码检查小时数是不是超过40了。如果是,代码计算超过40的小时数,然后用它乘上50块,然后把结果加到价格上。代码然后从工作的总时间里减去超过40小时的部分。把剩下的工作小时乘以25块,然后加到总价上。

    在上面的例子里,结果是这样的:
    1250

    有意思的是 if 语句里面的代码。有一个新常量的声明,hoursOver40,来保存超过40小时的数字。
    很明显你可以在if语句里面使用它。但如果你尝试在上面代码的结尾去使用它,会发生什么?

    ···
    print(price)
    print(hoursOver40)
    

    这会导致下面的错误:

    `error: use of unresolved identifier 'hoursOver40'(错误:使用了不确定的标识符‘hoursOver40’)`
    

    这个错误告诉你,你只被允许在创建 hoursOver40 常量的 scope 里使用它。这个例子里,if 语句引入了一个新 scope,所以当这个 scope 结束了,你就不能再使用这个常量了。

    但是,每个 scope 可以使用来自它的父 scope 的变量和常量。在上面的例子里,if 语句里面的scope使用了 price 和 hoursWorked 变量,他们就是在父 scope 被创建的。

    三目操作符(The ternary conditional operator)

    现在我想介绍一个新的操作符,你在第三篇文章里没有看到的。叫做三目操作符(The ternary conditional operator),它是和 if 语句相关的。

    如果你想判断两个变量最小的值和最小的值,你可以像这样使用if语句:

    let a = 5
    let b = 10
    
    let min: Int
    if a < b {
        min = a
    } else {
        min = b 
    }
    
    let max: Int
    if a > b {
        max = a 
    } else {
        max = b 
    }
    

    现在你知道这是怎么工作的了,但这有好多代码。如果你能把它缩短到就几行岂不是很好?唔,你可以的,感谢三目操作符!

    三目操作符带有一个情况,返回两个值其中之一,取决于那个情况是true还是false。语法如下所示:

     (<情况>) ? <TRUE值> : <FALSE值>
    

    你可以使用这个操作符来重写上面的长代码块,像这样:

    let a = 5
    let b = 10
    
    let min = a < b ?  a : b
    let max = a > b ? a : b
    

    第一个例子里,情况是a<b。如果是true,赋值回min的结果会是a;如果是false,结果会是b的值。

    我相信你也同意这样简单多了!这是一个有用的操作符,你会发现自己经常使用它。

    **注意:**因为找两个数字中更大的或更小的那个是如此常用的操作,Swift标准库为这个目标提供了两个函数:max和min。

    迷你练习

    创建一个叫做myAge的常量,初始化为你的年龄。写一个if语句,如果你的年龄在13到19之间,就print“青少年”,如果不是,就print“不是青少年”。

    Swift语句

    控制流程的另一种方式是使用 switch 语句,允许你根据变量或常量的值来执行不同的代码。

    这是一个非常简单的基于整数的 switch 语句:

    let number = 10
    switch (number) {
    case 0:
        print("零")
    default:
        print("非零")
    }
    

    这个例子,代码会如下输出:

    非零

    这个switch语句的作用是判断数字是不是零。但它可以做更复杂一点的事!

    要处理一个特殊情况,使用 case 后面跟着你想判断的值,这个例子里是0。然后,用default来表明,如果是所有其它值应该做点什么。

    这是另一个例子:

    let number = 10
    switch (number) {
    case 10:
        print("这是10!")
    default:
        break
    }
    

    这次你判断10,在case里print了一条消息。如果是其他值,那什么都不应该发生。当你不想让一个case或default发生任何事情的时候,那就用break关键字。这告诉Swift你不打算在这里写任何代码,任何事都不应该发生。

    当然,switch语句也可以处理整数以外的数据类型。他们可以处理任何数据类型!这是一个基于string的例子:

    let string = "狗"
    switch (string) {
    case "猫", "狗":
        print("这个动物是居家型。")
    default:
        print("这个动物不是居家型。")
    }
    

    这会print如下内容:

    这个动物是居家型。

    这个例子里,你为case提供了两个值,意味着如果值等于“猫”或“狗”,语句就会执行这个case。

    你也可以给switch语句不止一个case。你在这篇文章之前的部分看见了一个 if 语句带有 else-if 从句,可以把一天中的小时转换为描述这是一天中的哪个部分的字符串。你可以用一个switch语句来更简要的重写它,像这样:

    let hourOfDay = 12
    let timeOfDay: String
    switch (hourOfDay) {
    case 0, 1, 2, 3, 4, 5:
        timeOfDay = "清晨"
    case 6, 7, 8, 9, 10, 11:
        timeOfDay = "上午"
    case 12, 13, 14, 15, 16:
        timeOfDay = "下午"
    case 17, 18, 19:
        timeOfDay = "晚上"
    case 20, 21, 22, 23:
        timeOfDay = "夜深了"
    default:
        timeOfDay = "这他妈不是时间!"
    }
    print(timeOfDay)
    

    代码会 print 如下内容:

    下午

    如果有多个case,语句会执行第一个满足的case。你应该会同意这个例子比用if语句来的更简要和清晰吧。细节上其实也更严谨,因为 if 语句没法处理负数的情况,但这儿负数被正确地认为是无效的。

    基于一个值的property来匹配一个case的情况也是可以的。就像你在第三篇学的,你可以使用模除操作符来判断一个整数是偶数还是奇数。看看这段代码:

    let number = 10
    switch (number) {
    case let x where x % 2 == 0:
        print("偶数")
    default:
        print("奇数")
    }
    

    这会print如下内容:

    偶数

    这个switch语句使用了let-where语法,意味着case只会在一个特定情况是true的时候匹配。这个例子里,你设计了case来满足如果值是偶数的情况——那就是值模除2等于0啦。

    这个可以基于情况来匹配值的方法叫做模式匹配(pattern matching)

    另一种方式使用switch语句也有绝佳效果,像这样:

    let coordinates: (x: Int, y: Int, z: Int) = (3, 2, 5)
    switch (coordinates) {
    case (0, 0, 0): // 1
        print("原点")
    case (_, 0, 0): // 2
        print("在x轴上。")
    case (0, _, 0): // 3
        print("在y轴上。")
    case (0, 0, _): // 4
        print("在z轴上。")
    default:        // 5
        print("空间里的某个位置")
    }
    

    这个switch语句利用了部分匹配(partial matching)。按顺序说一下每个case都做了什么:

    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. 匹配剩下的坐标。

    用下划线来表示你不在乎这个值。你早在第二篇文章就见过了,会并会在贯穿教程的多个地方看见它。因为这太好用了!

    如果你不想忽略值,那你就能在switch语句里使用它,像这样:

    let coordinates: (x: Int, y: Int, z: Int) = (3, 2, 5)
    switch (coordinates) {
    case (0, 0, 0):
        print("原点")
    case (let x, 0, 0):
        print("在x轴上 x = \(x)")
    case (0, let y, 0):
        print("在y轴上 y = \(y)")
    case (0, 0, let z):
        print("在z轴上 z = \(z)")
    case (let x, let y, let z):
        print("空间里的某个位置 x = \(x), y = \(y), z = \(z)")
    }
    

    这里坐标轴 case 使用 let 语法来把有关值取出。代码然后使用字符串插入来构建一个字符串,把它 print 出来。

    注意为什么这个switch语句不需要一个default。这是因为最后的case本质上就是default—它匹配任何值,因为对元组的任一部分都没有限制。如果switch语句在cases里用光了所有可能的值,那就不需要什么default了。

    最后,你也可以用与之前看到的同样的let-where语法来匹配更复杂的情况。例如:

    let coordinates: (x: Int, y: Int, z: Int) = (3, 2, 5)
    switch (coordinates) {
    case (let x, let y, _) where y == x:
        print("在y = x线上。")
    case (let x, let y, _) where y == x * x:
        print("在y = x^2线上。")
    default:
        break
    }
    

    这里,你匹配了“y等于x”和“y等于x的平方”两条线。

    这些就是switch语句的基础啦!

    迷你练习

    1. 写一个switch语句,基于一个整数的年龄,然后print出这个年龄对应的年龄层。你可以自己做一个年龄层,或者用我的分类方法:0-2岁:幼儿,3-12岁:儿童,13-19岁:青少年,20-39岁:成年人,40-60:中年人;61+:老人。
    2. 写一个switch语句,基于包含了一个字符串和一个整数的元组。字符串是一个名字,整数是一个年龄。用和你在前一个练习同样的情况,用 let 语法来 print 出名字接着年龄层。例如,我自己就应该 print 出“张嘉夫是一个成年人。”

    关键点

    • 用 if 语句做基于一个情况的简单判断。
    • 在 if 语句里用 else 和 else-if 来为做判断扩展,不止一个单独的情况。
    • 你可以在简单 if 语句的地方用三目操作符。
    • 变量和常量属于一个特定的scope(范围),越过了scope就不能再用他们了。一个scope可以继承父scope的变量和常量。
    • 用 switch 语句来基于一个变量或常量的值决定运行哪段代码。
    • switch 语句的强大来自于它使用模式匹配的能力,因为值可以用复杂规则来进行比较。

    接下来去哪儿?

    Apps很少全程时刻都运行在同样的方式;根据来自网络或用户输入的内容,你的代码需要做判断去哪条路。有了if,else和switch语句,你可以让代码基于一些情况来做决定。

    和决定是否要做一些事相似,你也能决定做一些事多少次。在下一篇文章里,你会看到如何使用循环来多次重复步骤。

    挑战

    挑战A:你就是编译器

    下面的代码哪里错了?

    let firstName = "嘉夫"
    if firstName == "嘉夫" {
        let lastName = "张"
    } else if firstName == "阳" {
        let lastName = "刘"
    }
    let fullName = lastName + firstName
    

    挑战B:结果预测

    看看下面的switch语句:

    switch (coordinates) {
    case (let x, let y, let z) where x == y && y == z:
        print("x = y = z")
    case (_, _, 0):
        print("在x/y平面上")
    case (_, 0, _):
        print("在x/z片面上")
    case (0, _, _):
        print("在y/z平面上")
    default:
        print("没什么特别的")
    }
    

    在coordinates分别是下列每一个的时候,代码会 print 什么?

    let coordinates = (1, 5, 0)
    let coordinates = (2, 2, 2)
    let coordinates = (3, 0, 1)
    let coordinates = (3, 2, 5)
    let coordinates = (0, 2, 4)
    

    介绍

    欢迎来到Swift世界!Swift是一门苹果在2014年夏天发布的编程语言。从那之后,Swift发布了一个主要的版本跳跃,成为了开始在苹果平台:iOS,OS X,watchOS和tvOS开发的最简单的方式。

    谁适合这篇教程

    这篇教程适合懂一点编程、并且希望学习Swift的人。也许你已经为网站写过一些JavaScript代码,或者用Python写过一些简短的程序。这篇教程就是为你准备的!你会学习到编程的基本概念,同时也会成为Swift语言小能手。

    如果你是赤裸裸的编程新手,这篇教程也是为你准备的!教程里贯穿有简短的锻炼和挑战来给你一些编程练习,同时测试你的知识。

    需要准备什么

    要看这篇教程,你需要准备如下的东西:

    • 一台运行OS X El Captian(10.11)的Mac,带有最新发布的更新并且安装了安全补丁。这样你才能够安装需要的开发工具:最新版本的Xcode。
    • Xcode 7.3 或更新的版本。Xcode是用Swift写代码的主要开发工具。最小也需要Xcode 7.3版本,因为那个版本包含Swift 2.2。你可以免费从Mac App Store下载Xcode的最新版本,这里:http://apple.co/1FLn51R

    如果你还没有安装Xcode最新版本,在继续看下面的教程前要确定安装。

    如何使用这篇教程

    每篇教程都会介绍触手可及的话题理论,伴随大量Swift代码来示范在学习的实际的应用程序。

    教程里的所有代码都是平台中立的;这意味着不是为iOS、OS X或任何其它平台而特定。代码在playgrounds里运行,你在本篇中已经学习了。

    在剩下的教程里,你可以把代码在自己的playground里输入进去。这样你就可以和代码“玩耍”(play around),做一些改变立即就能看见代码运行的结果。

    剩下的教程里会贯穿实际小练习,都是简短的练习,关于触手可及的主题。每篇的末尾也有挑战,会有编程问题也会有长一点的代码练习来测试你的知识。做完就能掌握大部分的Swift基础知识。

    教程更新

    教程会随Swift语言的更新而更新,会发布在我的简书和知乎专栏上,搜索“张嘉夫”即可关注我。

    目录

    本教程从一些基础工作开始来让你起步:

    • 第1篇,编程本质 & Playground基础 - 这就是,到编程世界的入门介绍!你会从电脑和编程的预览开始,然后剩余时间给Swift playground打个招呼。
    • 第2篇,变量 & 常量 - 你会学习到变量和常量,这是用来存储数据的“地方”。你也会学习数据类型以及Swift如何追踪数据类型并在代码中进行传输。
    • 第3篇,数字类型 & 操作 - 你会从基础的数字类型比如整形和浮点型数字开始,当然也包括布尔类型。也会看到一些在实际操作,从比较到算数操作如加减。
    • 第4篇,字符串 - 用字符串来存储文字-从按钮里的文字到图片的标注到这篇教程全部的文字,存储这所有的一切!你会学习到string和character类型,以及基于这些类型的一些常见操作。

    在脑海中有基础数据类型后,就该用那些数据做一些事情了:

    • 第5篇,做判断 - 代码不总是直接从头运行到尾。你会学习在代码里如何做判决并且设定情况来运行某段代码。
    • 第6篇,重复步骤 - 继续不要让代码直线运行的主题,你会学习到如何使用循环来重复某些步骤。
    • 第7篇,函数 - 函数是Swift中用来构建代码的基础建筑。你会学习到如何定义函数来分组代码到可复用单元中。
    • 第8篇,闭包(Closures) - 闭包和函数很接近。你会学习到如何使用它们来轻松传递代码块。

    最后一篇会回到数据:

    • 第9节,可选值 - 这篇讲可选值,Swift中的一种特殊类型,表示既有可能是一个真实的值也有可能没有值。这篇的最后你会知道为什么要用可选值以及如何安全地使用它们。

    这些基础会让你快速开始Swift之路,做好接触更高级编程主题的准备。

    相关文章

      网友评论

        本文标题:一个下午让你掌握Swift基础 ( 5/9 ) 做判断

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