本文将提供最全面的元组实践,有大量代码供你参考!
本文承接上一篇文章有了数组和字典,Swift为何还需要元组?
元组的玩法,你学全了吗
既然元组这么有意思,它的各种用法我们也要学一学。
- 首先是元组的定义
0元的元组,虽然没有实际作用,但是语法上确实支持
var t0 : () = ()
等同于 var t0 : (Void) = ()
可以缺省类型 var t0 = ()
1元的元组,会被编译器优化为其实际元素的类型。举例:
var t1 : (String) = ("我是字符串")
等同于 var t1 : String = "我是字符串"
可以缺省类型 var t1 = "我是字符串"
注意!!!由于t1实际为String类型,因此t1.0的访问会报错
多元的元组的定义
var t2 : (String, Int) = ("李刚",34)`
也可以缺省类型 var t2 = ("李刚",34)`
元组也支持可选类型 var t2 : (String?, Int) = (nil,34)`
元组还支持元素命名
var t2 : (name:String, age:Int) = (name:"李刚",age:34)
赋值时可以省略命名 var t2 : (name:String, age:Int) = ("李刚",34)
定义类型可以整个缺省,赋值时添加 var t2 = (name:"李刚",age:34)
注意!!!如果定义的类型中没有命名,赋值的命名是无效的
var t2 : (String, Int) = (name:"李刚",age:34) 此时访问t2.name会报错
元组支持嵌套
var t_t : (String, (String, Int)) = ("基本信息", ("李刚",34))
可以将元组的类型重定义为一个类型名
typealias namedFishesType = (first:String, second:String, third:String)
let namedFishes: namedFishesType = ("cod", "dab", "eel")
- 接下来,元组的数据访问
当元素未命名时,采用自然顺序访问,序号从0开始
例如 var t2 = ("李刚",34)
name = t2.0
age = t2.1
当元素命名时,可以用命名访问数据,当然仍可以使用序号进行访问
例如 var t2 = (name:"李刚",34)
仍然可以用序号访问 name = t2.0
也可以用命名访问 name = t2.name
可以用多个变量同时进行访问
例如 var t2 = (name:"李刚",34)
var (name, age) = t2 即可同时获取name,age
var (name, _) = t2 不需要的参数可以缺省
另外注意,元组为数值类型,因此元组的拷贝是值拷贝
例如 var t2 = (name:"李刚",34)
var t2_copy = t2
t2.name = "王帅"
print(t2_copy.name) //输出为 李刚
关于元组的访问级别
元组的访问级别取决于它包含的元素,比如元组里的元素都是private级别的,那么该元组也是private级别的。 遵循最小的原则,也就是说如果一个元组中有两个元素,一个为private级别,另一个为public级别,那么该元组遵循最小原则,它的访问级别为private。
- 元组的数据修改
虽然元组的数据不能增删,但是修改还是可以的
var t2 = (name:"李刚",34)
t2.name = "王帅"
t2 = ("李教授", 45)
但是数据类型不能改变
t2.name = 11 //报错!!!
如果是常量定义,元组的数据不能改变
let t3 = (name:"李一",24)
t3.name = "李二狗" //报错!!!
当然,如果指定数据类型为Any,这种情况下数据可以改变类型
var t_any : (String, Any) = ("李一", 24)
t_any.1 = "可以改为String" //Any不限定数据类型
- 元组与Array、Dictionary的组合定义
数组嵌套元组
var moneyArray:[(Int,String)] = [(10,"Penny"), (15,"Nickle"), (3,"Quarter")]
字典嵌套元组
var userInfoDic:[String, (Int,String)] = ["peny":(10,"girl"), "nakl":(15,"boy")]
- 元组的常见使用场景
非常适用于Dictionary遍历
//官方文档上的例子
var airports: [String: String] = ["YYZ": "Toronto Pearson", "DUB": "Dublin"]
//遍历airports
for (airportCode, airportName) in airports {
print("\(airportCode): \(airportName)")
}
非常适合用于Array的enumerate()
//官方文档上的例子
var shoppingList = ["Eggs", "Milk"]
for (index, value) in shoppingList.enumerate() {
print("Item \(index + 1): \(value)")
}
适合函数返回多元数据
func userInfo() ->(String, Int) {
return ("李刚", Int)
}
函数也可以返回可选元组,即可以返回nil
func userInfo() ->(String, Int)? {
return nil
}
当然也可以部分元素为可选
func userInfo() ->(String?, Int) {
return (nil, 34)
}
甚至可以用来给函数传递多元参数
//定义一个函数,有number和text两个参数
func doSomething(number: Int, text: String) {
println("\(number): \(text)")
}
//正常调用方式
doSomething(1, "one")
//元组调用方式
let var tupleVar = (1, "one")
doSomething(tupleVar)
- 高级实例
假设有一个数组
//模拟情绪数据
var emotions : [(type : String, strength: Int)] = [("happy",0),("scared",0),("tender",0)]
我想遍历数组,然后对happy
进行+1,应怎么做?
for (ix,emo) in enumerate(emotions) {
if emo.type == "happy" {
emotions[ix] = (type:emo.type,strength:emo.strength+1)
}
}
有没有更高级的做法?有!
//这里用到了map,具体方法可以google一下,本文不涉及
emotions = emotions.map {
emo in
if emo.type == "happy" {
return (type:emo.type,strength:emo.strength+1)
} else {
return emo
}
}
总结
上一篇文章有了数组和字典,Swift为何还需要元组?我们解释了为什么需要元组,之后对比了tuples与array、dictionary的优劣区别。而本文则给出了大量的实例,元组的知识全在这里了。
相信你已经非常了解元组的使用,这篇文章参考了很多资料,我整理了两天,希望大家喜欢,给个赞
参考资料
CodingExplorer: Tuples in Swift: Create, Read, and Return
swiftmi: Swift中元组(Tuples),结构体(Struct),枚举(Enums)之间的区别
swiftmi: Swift中的元组(Tuples)
Swift2.1苹果官方文档
Stackoverflow: Why use tuples in swift?
Stackoverflow: Can't change tuple in array, why?
Stackoverflow: How do i add a tuple to an array?