有了数组和字典,为何Swift还需要元组(tuples)?

**### 为什么需要元组

为了回答这个问题,首先让我们脑补一个例子:\
假设有一个班级,数学科目经常小测((⊙o⊙)),数学老师非常用心的把每次成绩都记录下来了。如果我要拿到小明同学最近5次的数学成绩,应该怎么定义数据格式?

首先回顾一下,在c的时代,数据类型有这么几类:

基本类型构造类型指针类型空类型
整型 short int long数组 []指针 *void
浮点型 float double结构体 struct\
\
字符类型 char共用体 union\
\
布尔类型 bool (C99增加)枚举类型 enum\
\

用c语言有限的数据类型,要怎么定义需要的数据呢?

char* name = "小明";
float scores[5] = {90,87,88.5,95,78};

看上去还不太复杂。\
再进一步想,如果实现一个c函数,由函数返回这些数据,怎么办?只能定义struct了。

//先声明一个struct
struct name_scores {
    char *name;
    float scores[5];
};

//给struct赋值
struct name_scores xiaoming = {"小明" , {90,87,88.5,95,78}};

//函数返回类型是结构体
return xiaoming;

这个解决方案,看上去真是just so so。

到了c++的时代,似乎可以试试类的概念,把char*也换成string。

//先声明一个类
class Student {
  public:
    string name;
    float scores[5];
};

//实例化一个对象,赋值
Student xiaoming;
xiaoming.name = "小明";
xiaoming.scores = {90,87,88.5,95,78};

//函数中返回对象
return xiaoming;

然并卵,更麻烦了。

到了乔老爷子的时代,oc语言增加了NS开头的基本数据类,NSString NSArray NSDictionary都是非常常用的,我们可以试着组合一下数据。

//存储数据
NSString *name = @"小明";
NSArray *scores = @[@90,@87,@88.5,@95,@78];
NSDictionary *returnDic = @{@"name":name,@"scores":scores};

//返回字典
return returnDic;

这已经是最简单的写法,依然是比较复杂的形式。

所以,有没有一种简单的数据类型,可以轻松组合不同类型的数据?\
有!\
Swift的元组闪亮登场✨✨

//一行代码搞定
return ("小明",(90,87,88.5,95,78))

哇,只需一行代码,你买不了吃亏,买不了上当,元组就是这么霸气!\
有些人可能就不服气了,数组一样可以这么简洁,为什么不用数组?客官请继续看。

元组、数组、字典,合适才是最好

首先说说字典,字典是key:value键值对,它适合将不同种类、不同用途的数据组合在一起,通过key值进行索引。

优点:

  1. 通过key值进行索引,查找效率高
  2. 通过key值进行数据标注,可读性高,易于区分多种数据
  3. key值唯一,增删改可以保证数据唯一性

缺点:

  1. 一个value必须对应一个key,尽管有时不需要key
  2. key值顺序不定,字典对key值表进行了hash,所以不方便存储对顺序敏感的数据

具体到小明的例子,数据格式如下

var name_score : Dictionary = ["name":"小明","scores":[90,87,88.5,95,78]]

我们试着读取其中的数据

var name = name_score["name"]  //打印值为Optional(小明)
var scores = name_score["scores"]  //打印值为Optional((90,87,88.5,95,78))

而如果print(name_score),会发现输出的key值顺序发生了变化

字典输出,观察key值顺序


接下来,我们再看看数组。\
最早在c语言中,数组用来存储多个相同类型的数据,到了OC不再限定存储数据的类型,Swift也沿用了OC的传统。这也是小明的例子中争议的来源,用数组也可以解决问题呀。

那么我们说说数组的优缺点吧。

优点

  1. 数据存储顺序固定,增删改也通过index来进行
  2. 集成了遍历方法,适合对大量同类数据的处理
  3. 不需要定义key,写法相对简单

缺点

  1. 访问特定数据时,查找效率不高
  2. 处理特定数据时,需要牢记数据的index,可读性不好,容易产生错位处理

仍以小明为例

var name_score = ["小明",[90,87,88.5,95,78]]

访问数据的方式如下

var name = name_score[0]  //打印值为小明
var score = name_score[1]  //打印值为(90,87,88.5,95,78)

我们print(name_score),可以看一下结果

数组输出,顺序很重要


Swift已经对Array和Dictionary做了大量改良,非常方便使用。可是元组又可以为我们带来什么呢?

  • 首先,当我们在Array中放置不同类型的数据时,我们无法再对每个数据的type做定义。\
    ["小明",[90,87,88.5,95,78]]可以被修改为[1,[90,87,88.5,95,78]],而1显然不是正确的名字格式\
    而元组可以定义元素的类型\
    var tuple : (String, Array) = ("小明",[90,87,88.5,95,78])\
    更深一步,元组嵌套元组每一个元素的类型都可以定义\
    var tuple : (String, (Float,Float,Float,Float,Float)) = ("小明",(90,87,88.5,95,78))

  • 其次,数组的元素个数可能发生改变,我可以增加、删除元素\
    name_score.append("添加一个字符串")\
    name_score.removeAtIndex(1)\
    而元组一旦定义,其元素个数确定,不能增加、删除

  • 字典必须定义key,而元组不需要。当然,如有必要,你还可以为每个元素命名

    var tuple = (name:"小明",[90,87,88.5,95,78])\
    tuple.name 等同于 tuple.0

  • 字典的存储顺序不确定,而元组是固定的

通过上面几个简单的对比分析,我们发现,元组综合了数组、字典、甚至struct的一些优点,是对数据类型的一个强力补充。

下面分析一下元组的优缺点。

优点

  1. 元组可以同时存储多种类型元素,且元素类型固定,以保证数据安全,除非你定义数据类型为Any。编译器会对赋值参数类型进行检查
  2. 元组的元素个数固定,不允许增加、删除,编译器会严格校验赋值参数个数
  3. 无需定义key,但是必要时可以为数据命名,方便数据访问
  4. 适合同时遍历多元数据,例如官方文档的例子\
    for (index, value) in shoppingList.enumerate()

缺点

  1. 不适合存储大量数据,因为元组不支持append、remove等方法
  2. 考虑到工程实际情况,后端使用的语言可能不支持元组,需要转换为其他格式

所以说,元组适合应用于组合少量的多元的数据,与数组、字典结合使用可以产生强大威力。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值