另外一种下标的方法也可以修改特定的的键对应的值,但是该方法返回的值是更新前的值:
var airport:[String: String] = ["YYZ":"Toronto Pearson","DUB":"Dublin"]
if let oldValue = airport.updateValue("Dublin", forKey: "DUB"){
print("The old value for DUB was \(oldValue).")
}
下面的例子说明women可以通过下标语法表示这样一种场景,我们通过下标语法来获取到一个可选值,如果没有获取到则返回一个nil值
if let airportName = airport["hah"]{
print("The name of the airport is \(airportName)")
}else{
print("That airport is not in the airports dictionary.")
}
因为没有hah这个键所对应的值,所以if判断获取的是一个nil值,打印That airport is not in the airports dictionary.我们还可以通过下表语法来从下标语法中新增一个键值对,通过给键的值赋值nil来从字典中移除一个键值对
airport["nihao"]="jiangyaqi" //新增键值对nihao:jiangyaqi
airport["nihao"]=nil //删除键值对nihao:jiangyaqi
此外可以通过removeValueForKey方法来从字典中移除键值对,这个方法会对兼职对存在的情况下移除键值对并返回该键值对,键值对不存在的情况下返回nil
if let removedValue = airport.removeValueForKey("DUB"){
print("The removed airport's name is \(removedValue).")
}else{
print("The airports dictionary does not contain a value for DUB.")
}
打印出The removed airport's name is Dublin
字典的遍历
我们可以用for-in循环来遍历字典中得键值对,每个字典的数据都以(key,value)元组的形式返回,我们还可以使用临时常量或者变量来分解这些元组
for (aiportCode,airportName) in airport{
print("\(aiportCode):\(airportName)")
}
//或者我们可以直接访问keys后者values属性
for airportCode in airport.keys{
print("Airport code: \(airportCode)")
}
for airportName in airport.values{
print("Airport name: \(airportName)")
}
如果我们只是需要使用某个字典的键值对或者值集合作为某个接受Array实例的API的参数,可以使用keys或者values属性构造一个新数组:
let airportCode = [String](airport.keys)
//构造了一个以airport.keys为值的新数组
let airportNames = [String](airport.values)
//构造了一个以airport.values为值的新数组
Swift的字典是无序的集合,为了以特定的顺序来遍历数组或者键或者值,可以对字典的keys或者values属性使用sort方法
闭包
现在我理解的闭包作用是这样的,就是闭包可以将本来是一个函数的东西,作为参数进行传递。可能现在理解有偏差,以后再看。现在理解swift中得函数就是闭包,apple文档中是这么描述的
闭包有三种形式:
- 全局函数是一个有名字但不会捕获任何值的闭包。
- 嵌套函数是一个有名字并可以捕获到其封闭函数域内的值的闭包。
- 闭包表达式是一个利用轻量级语法所写的,可以捕获其上下文中变量或常量值的匿名闭包。
sort方法
swift标准库提供了sort方法,会根据你提供的用于排序的闭包函数将已知类型数组中得值进行排序,一旦排序完成会返回一个跟原数组大小相同,包含同类型元素且已经正确排序的新数组,原数组不会被修改。sort方法接收一个闭包,该闭包函数需要传入跟数组元素类型相同的两个值,并且返回一个布尔类型的值来表明当排序结束后传入的第一个参数排在第二个参数的前面还是后面,如果第一个参数出现在第二个参数的前面,排序闭包函数不要返回true,反之返回false。
我们命名了一个数组names
let names = ["Chirs","Alex","Ewa","Barry","Daniella"]
提供一个闭包函数的一种方式是撰写一个符合类型要求的普通函数,并将其作为sort方法的参数传入
func backwards(s1: String, s2: String) -> Bool {
return s1 > s2
}
//对于字符串来说,大于表示的十按照字母顺序较晚的出现
var reversed = names.sort(backwards)
// reversed 为 ["Ewa", "Daniella", "Chris", "Barry", "Alex"]
闭包表达式语法(Closure Expression Syntax)
闭包表达式的语法一般如下:
{(parameters) -> returnType in
statements
}
下面的例子展示了之前函数对应的闭包表达式版本的代码,闭包的函数体部分由关键字in引入,该关键字表示闭包的参数和返回值类型的定义已经完成,闭包函数体将要开始:
reversed = names.sort({ (s1: String, s2: String) -> Bool in
return s1 > s2
})
这个闭包的函数体部分很短,我们可以写成一行:
reversed = names.sort({ (s1: String, s2: String) -> Bool in return s1 > s2})
这个例子中得sort方法的整体调用保持不变化,一对圆括号包裹住了方法的整个参数,然而参数现在变成了内联闭包
根据上下文推断类型(Inferring Type From Context)
实际上任何情况下,通过内联闭包表达式构造的闭包作为参数传递给函数或者方法的时,够可以推断除闭包的参数和返回值类型,也就是说闭包作为函数或者方法的参数的时候,我们几乎不需要用完整地格式构造内联闭包。
reversed = names.sort(s1 : s2 in return s1 > s2)
单行表达式闭包隐式返回(Implicit Return From Single-Expression Closures)
单行表达式闭包可以通过省略return关键字来隐式返回单行表达式的结果,sort方法的第二个参数函数类型明确了闭包必须返回一个Bool类型的值,因为闭包函数体只包含了一个单一的表达式s1 > s2,该表达式返回Bool类型值,因此这里没有歧义,return关键字可以省略:
reversed = names.sort({s1, s2 in s1 > s2})
参数名称缩写(Shortthand Argument Names)
Swift自动为内联函数闭包提供了参数名称缩写的功能,可以直接通过$0,$1,$2来顺序调用闭包的参数,以此类推。我们在闭包表达式中使用了参数名称的缩写,我们就可以在闭包参数列表中省略对其的定义,并且对应的参数名称缩写的类型会通过函数类型进行判断,所以in关键字也可以省略:
reversed = names.sort({ $0 > $1 })
//$0和1,表示了闭包中第一个和第二个String类型的参数
运算符函数(Operator Functions)
swift中String类型定义了关于(>)大于号的字符串实现,其作为一个函数接收两个String并且返回一个Bool类型的值,这个正好和sort方法中得第二个参数需要的函数类型相符合。因此可以写成:
reversed = names.sort(>)