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

0.625字数 823阅读 5700

本文将提供最全面的元组实践,有大量代码供你参考!

本文承接上一篇文章有了数组和字典,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?

推荐阅读更多精彩内容