您的位置:首页 > 移动开发 > Swift

Swift元组(tuples)最佳代码实战

2017-09-29 16:03 375 查看

元组的玩法,你学全了吗

既然元组这么有意思,它的各种用法我们也要学一学。

首先是元组的定义

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