字符串的使用
1.1 问题
Swift的String和Character类型提供了一个快速的,兼容Unicode的方式来处理代码中的文本信息。创建和操作字符串的语法与C语言中字符串类似。本案例将学习如何操作Swift中的字符串。
1.2 方案
首先初始化字符串,可以直接在代码中包含一段预定义的字符串作为字符串字面量,字符串字面量是由双引号引起来的,具有固定顺序的文本字符集。
字符串的字面量可以包含以下转义符:
\0(空字符)、\\(反斜线)、\t(水平制表符)、\n(换行符)、\r(回车符)、\"(双引号)、\'(单引号)。
初始化以个空字符串可以创建一个空字符串作为初始值,也可以初始化一个新的String实例。
其次遍历字符串可以使用for-in循环来访问字符串的每个字符。
然后连接字符串和字符可以通过加法运算或者加法赋值运算来实现,append方法可以将一个字符添加到字符串变量的尾部。
往字符串中插入常量、变量、字面值或者表达式可以使用\()。
可以使用count函数获取字符串的长度。
最后字符串的其他操作:
比较字符串可以使用双等号==,结果返回一个布尔值;
可以使用hasPrefix和hasSuffix方法来检查字符串特定的前缀和后缀;
可以通过字符串的uppercaseString和lowercaseString属性来访问字符串的大写版本和小写版本。
1.3 步骤
实现此案例需要按照如下步骤进行。
步骤一:初始化字符串
首先初始化字符串,可以直接在代码中包含一段预定义的字符串作为字符串字面量,字符串字面量是由双引号引起来的,具有固定顺序的文本字符集。
初始化以个空字符串可以创建一个空字符串作为初始值,也可以初始化一个新的String实例,可以通过isEmpty方法来判断字符串是否为空,代码如下所示:
- varemptyString = ""
- varanotherEmptyString = String()
- ifemptyString.isEmpty {
- println("啥也没有.")
- }
运行结果如图-1所示:
图-1
步骤二:字符串的遍历
可以使用for-in循环来访问字符串的每个字符,代码如下所示:
- //字符串的遍历
- for character in "Dog" {
- println(character)
- }
运行结果如图-2所示:
图-2
步骤三:连接字符串和字符
连接字符串和字符可以通过加法运算或者加法赋值运算来实现,append方法可以将一个字符添加到字符串变量的尾部,代码如下所示:
- //字符串的可变新和拼接字符串
- let constStr = "常量字符串"
- varvarString = "变量字符串"
- varString = constStr + varString
- varString += "再加一个字符串"
- letch:Character = "!"
- varString.append(ch)
运行结果如图-3所示:
图-3
往字符串中插入常量、变量、字面值或者表达式可以使用\(),代码如下所示:
- //字符串中插入变量或常量
- let multiplier = 3
- let message = "\(multiplier)乘以2.5的结果是\(Double(multiplier)*2.5)"
运行结果如图-4所示:
图-4
可以使用count函数获取字符串的长度,代码如下所示:
- //字符串的长度,运行结果是13
- letnum = count(message)
步骤四:字符串的其他操作
比较字符串可以使用双等号==,结果返回一个布尔值,代码如下所示:
- //字符串的比较
- let quotation = "我们是一样的"
- let sameQuotation = "我们是一样的"
- if quotation == sameQuotation {
- println("这两个字符串是一样的")
- }
运行结果如图-5所示:
图-5
可以使用hasPrefix和hasSuffix方法来检查字符串特定的前缀和后缀,代码如下所示:
- //字符串的前缀和后缀
- lettarena = "tarene"
- iftarena.hasPrefix("t") {
- println("这个字符串以t开头")
- }
运行结果如图-6所示:
图-6
可以通过字符串的uppercaseString和lowercaseString属性来访问字符串的大写版本和小写版本,代码如下所示:
- //字符串的大小写
- let normal = "Hello World"
- letshouty = normal.uppercaseString
- let whispered = normal.lowercaseString
运行结果如图-7所示:
图-7
1.4 完整代码
本案例中,完整代码如下所示:
- importUIKit
- letstr = "Hello world!"
- //创建空字符串
- varemptyString = ""
- varanotherEmptyString = String();
- ifemptyString.isEmpty {
- println("这是空字符串")
- }
- //字符串的遍历
- for character in "Dog" {
- println(character)
- }
- //字符串的可变新和拼接字符串
- let constStr = "常量字符串"
- varvarString = "变量字符串"
- varString = constStr + varString
- varString += "再加一个字符串"
- letch:Character = "!"
- varString.append(ch)
- //字符串中插入变量或常量
- let multiplier = 3
- let message = "\(multiplier)乘以2.5的结果是\(Double(multiplier)*2.5)"
- //字符串的长度
- letnum = count(message)
- //字符串的比较
- let quotation = "我们是一样的"
- let sameQuotation = "我们是一样的"
- if quotation == sameQuotation {
- println("这两个字符串是一样的")
- }
- //字符串的前缀和后缀
- lettarena = "tarene"
- iftarena.hasPrefix("t") {
- println("这个字符串以t开头")
- }
- //字符串的大小写
- let normal = "Hello World"
- letshouty = normal.uppercaseString
- let whispered = normal.lowercaseString
2 switch语句的使用
2.1 问题
Swift中的switch语句和C语言中的switch语句有很大的不同,本案例将学习如何使用Swift中的switch语句。
2.2 方案
Swift中switch语句的不同:
switch语句必须是完备的,也就是每一种可能的值都必须至少有一个case分支与之对应,在某些不可能涵盖所有值的情况下,可以使用默认分支default,默认分支必须在switch语句最后;
没有隐式贯穿,如果需要贯穿则需要使用关键字fallthrough;
一个case可以有多个匹配模式;
可以在适当的时候使用break提前结束switch语句。
2.3 步骤
实现此案例需要按照如下步骤进行。
步骤一:switch语句的基本使用
使用switch语句来匹配一个常量x,代码如下所示:
- let x = 5
- switch x {
- case 1:
- println("x==1")
- case 2,3,4,5,6,7,8:
- if x==5 {
- println("x==5")
- //提前结束switch
- break
- }
- println("x>=2 && x<=8")
- default:
- println("default")
- }
上面的代码中第二个case匹配多个模式,默认分支保证了switch语句的完备性,运行结果如图-8所示:
图-8
步骤二:关键字fallthrough的使用
和C语言不同,Swift中的switch语句不存在隐式贯穿,当匹配的case分支中的代码执行完毕后,程序会终止switch语句,而不会继续执行下一个case分支。
如果需要贯穿,可以在每个需要该特性的case分支中使用fallthrough关键字,代码如下所示:
- //关键字fallthrough的使用
- letintergerToDescribe = 6
- var description = "数值\(intergerToDescribe)是"
- switchintergerToDescribe {
- case 2,3,5,7,11,13,17,19:
- description += "一个素数,并且是"
- fallthrough
- default:
- description += "一个整数"
- }
运行结果如图-9所示:
图-9
步骤三:case分支中使用范围
case分支的模式也可以是一个值的区间,下面的例子展示了如何使用区间匹配对应输出的内容,代码如下所示:
- let count = 3_000_000_000_000
- let countedThings = "宇宙中星星的数量"
- varnaturalCount : String //保存描述信息
- switch count {
- case 0:
- naturalCount = "没有"
- case 1...9:
- naturalCount = "极少"
- case 10...99,100..<500:
- naturalCount = "少许"
- case 500...999:
- naturalCount = "成百上千"
- case 1000 ..< 1_000_000:
- naturalCount = "成千上万"
- default:
- naturalCount = "亿万"
- }
运行结果如图-10所示:
图-10
步骤四:数据类型没有限制
和C语言不同,switch后面的表达式结果的数据类型没有限制,不仅仅局限于整型,代码如下所示:
- let vegetable = "红辣椒"
- switch vegetable {
- case "芹菜":
- let vegetableComm = "加点葡萄干伴道蚂蚁上树"
- case "黄瓜","豆瓣菜":
- let vegetableComm = "制作三明治"
- case let x where x.hasSuffix("辣椒"):
- let vegetableComm = "是很辣很辣的那种\(x)吗?"
- default:
- let vegetableComm = "搞个乱炖算了"
- }
运行结果如图-11所示:
图-11
2.4 完整代码
本案例中,完整代码如下所示:
- importUIKit
- let x = 5
- switch x {
- case 1:
- println("x==1")
- case 2,3,4,5,6,7,8:
- if x==5 {
- println("x==5")
- //提前结束switch
- break
- }
- println("x>=2 && x<=8")
- default:
- println("default")
- }
- //关键字fallthrough的使用
- letintergerToDescribe = 6
- var description = "数值\(intergerToDescribe)是"
- switchintergerToDescribe {
- case 2,3,5,7,11,13,17,19:
- description += "一个素数,并且是"
- fallthrough
- default:
- description += "一个整数"
- }
- //在case中使用范围
- let count = 3_000_000_000_000
- let countedThings = "宇宙中星星的数量"
- varnaturalCount : String //保存描述信息
- switch count {
- case 0:
- naturalCount = "没有"
- case 1...9:
- naturalCount = "极少"
- case 10...99,100..<500:
- naturalCount = "少许"
- case 500...999:
- naturalCount = "成百上千"
- case 1000 ..< 1_000_000:
- naturalCount = "成千上万"
- default:
- naturalCount = "亿万"
- }
- //数据类型没有限制
- let vegetable = "红辣椒"
- switch vegetable {
- case "芹菜":
- let vegetableComm = "加点葡萄干伴道蚂蚁上树"
- case "黄瓜","豆瓣菜":
- let vegetableComm = "制作三明治"
- case let x where x.hasSuffix("辣椒"):
- let vegetableComm = "是很辣很辣的那种\(x)吗?"
- default:
- let vegetableComm = "搞个乱炖算了"
- }
3 元组的使用
3.1 问题
元组是Swift语言中特有的数据类型,它将多个值组合成一个复合值,元组内的值可以是任意类型,并不一定相同,元组在作为函数返回值时非常有用。本案例将学习如何使用元组,包括元组的定义和访问,元组和switch语句结合使用等。
3.2 方案
元组的定义和访问:
可以把任意顺序的类型组合成一个元组,这个元组可以包含所有类型;
可以将一个元组的内容分解成单独的常量和变量,以便正常使用,如果只需要一部分元组值可以将需要忽略的部分使用下划线进行标记;
访问元组中的元组可以使用下标,下标从零开始;
还可以在定义元组时给每个元素进行命名,这样就可以通过元素名称来访问元组的元素。
元组和switch语句:
可以使用元组在同一个switch语句中测试多个值;
元组中的元素可以是值,也可以是区间;
使用下划线来匹配所有可能的值;
可以在case分支中进行值绑定;
case分支可以使用where关键字来增加额外的判断条件
3.3 步骤
实现此案例需要按照如下步骤进行。
步骤一:元组的定义和访问
下面的例子分别使用了不同的方式定义和初始化元组,代码如下所示:
- let http404Errot = (404,"Not Found")
- letonePerson:(Int ,String,Double) = (001,"Tarena",5000)
- var http200Status = (200,"OK")
- var point = (x:0,y:0)
运行结果如图-12所示:
图-12
接下来分别使用下标和元素名称的方式访问元组的元素,代码如下所示:
- //元组的访问
- let (status,description) = http404Errot
- status
- description
- let (statusCode,_) = http200Status
- statusCode
- //通过下标访问
- var code = http404Errot.0
- var describe = http404Errot.1
- http200Status.0 = 201
- http200Status.1 = "Unknown"
- //通过元素名称访问
- println("\(point.x),\(point.y)")
- varanotherPerson = (id:002, name:"Guodh", salary:60000.0)
- anotherPerson.name = "Guodenghong"
- anotherPerson.salary += 20000.0
- anotherPerson.0
运行结果如图-13所示:
图-13
步骤二:元组和switch语句
下面的例子展示如何使用一个(Int,Int)类型的元组来分类图-14中的点,switch语句会判断某个点是否在原点(0,0),是否在红色的x轴上,是伐在黄的y轴上,以及是否在一个以原点为中心的4*4的矩形里,或者在这个矩形外代码如下所示:
图-14
- letonePoint = (0,1)
- switchonePoint {
- case (0,0):
- println("在原点")
- case (_,0):
- println("在x轴上")
- case(0,_):
- println("在y轴上")
- case(-2...2,-2...2):
- println("在4*4的矩阵内")
- default:
- println("在4*4的矩阵外")
- }
运行结果如图-15所示:
图-15
case分支语句的模式允许将匹配的值绑定到一个临时的常量或变量,一旦绑定了常量或变量就可以在case分支里面使用,代码如下所示:
- letanotherPoint = (1,0)
- switchanotherPoint {
- case (let x ,0):
- println("点在x轴上,且x的值为\(x)")
- case (0,let y):
- println("点在y轴上,且y的值为\(y)")
- case let(x,y):
- println("点不在x轴上也不在y轴上,点的位置为(\(x),\(y))")
- }
上面代码中的三个case都声明了常量x和y,用于临时获取元组anotherPoint的一个或两个值,一旦声明了这些常量就可以在其对应的case分支里引用,运行结果如图-16所示:
图-16
case分支语句可以使用where关键字来增加额外额判断条件,接下来使用switch语句来判断某个点是否在图-17中的绿色或紫色的对角线上,代码如下所示:
图-17
- //使用where关键字增加额外的判断条件
- letyetAnotherPoint = (1,2)
- switchyetAnotherPoint {
- case let(x,y) where x == y:
- println("(\(x),\(y))在直线x==y上")
- case let(x,y) where x == -y:
- println("(\(x),\(y))在直线x==-y上")
- case let(x,y):
- println("不在两条斜线上")
- }
上面的代码中三个case都声明了常量x和y,用于临时获取元组yetAnotherPoint的两个值,这些常量被用作where语句的一部分,仅当where语句的条件为true时,匹配到case分支才被执行,运行结果如图-18所示:
图-18
3.4 完整代码
本案例中,完整代码如下所示:
- importUIKit
- //元组的定义
- let http404Errot = (404,"Not Found")
- letonePerson:(Int ,String,Double) = (001,"Tarena",5000)
- var http200Status = (200,"OK")
- var point = (x:0,y:0)
- //元组的访问
- let (status,description) = http404Errot
- status
- description
- let (statusCode,_) = http200Status
- statusCode
- //通过下标访问
- var code = http404Errot.0
- var describe = http404Errot.1
- http200Status.0 = 201
- http200Status.1 = "Unknown"
- //通过元素名称访问
- println("\(point.x),\(point.y)")
- varanotherPerson = (id:002, name:"Guodh", salary:60000.0)
- anotherPerson.name = "Guodenghong"
- anotherPerson.salary += 20000.0
- anotherPerson.0
- //元组和switch
- letonePoint = (0,1)
- switchonePoint {
- case (0,0):
- println("在原点")
- case (_,0):
- println("在x轴上")
- case(0,_):
- println("在y轴上")
- case(-2...2,-2...2):
- println("在4*4的矩阵内")
- default:
- println("在4*4的矩阵外")
- }
- //值绑定
- letanotherPoint = (1,0)
- switchanotherPoint {
- case (let x ,0):
- println("点在x轴上,且x的值为\(x)")
- case (0,let y):
- println("点在y轴上,且y的值为\(y)")
- case let(x,y):
- println("点不在x轴上也不在y轴上,点的位置为(\(x),\(y))")
- }
- //使用where关键字增加判断条件
- letyetAnotherPoint = (1,2)
- switchyetAnotherPoint {
- case let(x,y) where x == y:
- println("(\(x),\(y))在直线x==y上")
- case let(x,y) where x == -y:
- println("(\(x),\(y))在直线x==-y上")
- case let(x,y):
- println("不在两条斜线上")
- }