
课程咨询: 400-996-5531 / 投诉建议: 400-111-8989
认真做教育 专心促就业
对于Objective-C的开发者,元组类型是个有些陌生的概念。开发者可能会把元组和结构或类产生混淆。但事实上,元组比前面两者更加基础。喜欢把元组看做一个微型结构体或精简版结构体,该说法只用在极小的领域内,并随后被丢弃。
根据武汉达内ios培训获悉Apple关于SwiftTypes的官方文档:
元组类型是用括号包围,由一个逗号分隔的零个或多个类型的列表。
它是由其它类型组合而成的类型。元组可能包含零或多个类型,比如字符串、整数、字符、布尔以及其它元组。同时请注意,元组是*值传递,而不是引用。
Objective-C
letfoo=(0,false,“Hello”)
上面是一个包含三个独立元素的元组,如果需要用较冗长的方式声明,也可以把上面的元组定义为:
Objective-C
letfoo:(Int,Bool,String)=(0,false,“Hello”)
如果我们想访问来自这些来自元组的单独元素,我们可能不得不使用类似数组的索引来访问:
Objective-C
print(foo.0)//print:“0”
print(foo.1)//print:“false”
print(foo.2)//print:“Hello”
但愿/现在你能很好理解该元组的语法。下面将以混合方式创建包含其他元组的新元组。初期样式:
Objective-C
letbar:(Int,(Bool,String))=(1,(false,“Hello”))
print(bar.0)//print:“0”
print(bar.1.0)//print:“false”
print(bar.1.1)//print:“Hello”
这绝对疯狂,该点语法起初开起来像申请某物的某种语法版本。其原因是其在索引号为1的值类型是另一个元组,因此它使用了自己的存取器。
但是,为了避免使用索引,这必须记住与索引对应的值/,好的做法是尽可能地给你的元组属性命名。
Objective-C
letperson=(age:28,isTall:false,name:“Andyy”)
print(person.age)//print:“28”
print(person.isTall)//print:“false”
print(person.name)//print:“Andyy”
何处该用元组
当你想让一个函数能够返回多种类型时,这是元组的佳使用场景。/如果你是Objective-C开发者,这个概念听起来有些奇怪,甚至是不可能的。我们之前为了解决这种问题,我们通常不得不返回一个NSArray或NSDictionary。尽管如此,这种解决方案是危险的。因为一旦我们把NSArray转换成错误类型的对象,并调用指定方法会发生什么?这会导致在应用在运行时的闪退。
因此,让我们看看我们如何写出一个返回多种/类型的函数,而不是为了应对Objective-C的局限性而想出一个麻烦的方案。
Objective-C
typealiasPerson=(age:Int,isTall:Bool,name:String)
funcgetMultipleValues()->Person{
letperson:Person=(age:28,isTall:false,name:“Andyy”)
returnperson
}
letandyy=getMultipleValues()
print(andyy.age)//print:"28"
print(andyy.isTall)//print:"false"
print(andyy.name)//print:"Andyy"
为了提高代码可读性,我使用typealias预定义构造元组,也许你也该这样写,这样防止了在代码中意外地错误修改它的结构。
但是,正如你在上面看到的,这里有个叫做getMultipleValues()函数,它返回了一个包含三个独立的和不同数据类型的元组,每一个都有自己对应的变量名。
结构实例(不建议使用)
更新:Swift3.0将会废弃建议:SE-0029从函数应用里移除元组隐式转换
在文章的开头,我戏称元组为精简版结构体。一个鲜为人知的事实是,元组可以用来实例化结构体。
Objective-C
letsize=CGSize(width:100,height:100)
结构体CGSize有两个元素,其中任何一个都可以是CGFloat、Double或Int。但是,如果我们传递一个元组进入这个函数会发生什么?
Objective-C
letarguments:(width:CGFloat,height:CGFloat)=(100,100)
varsize=CGSize(arguments)
是不是很酷?但是有一点需要注意,元组的值必须和结构的构造函数的参数完全匹配,更改顺序、参数名称、数量,都会导致阻止Xcode继续编译。
Objective-C
letarguments:(height:CGFloat,width:CGFloat)=(100,100)
!!varsize=CGSize(arguments)
“不能通过‘(height:CGFloat,width:CGFloat)’参数列表调用‘CGSize’类型的初始化”——Xcode
你看我做了什么?我通过交换高度和宽度的位置,改变了参数的布局。尽管它们都叫做CGFloats,编译器不能推断出你想要做什么。
有趣的事实
如果曾使用过Swift,你很可能在不知道的情况下已经使用元组作为返回类型了。下面,我们有三个单独的函数,它们都做了相同的事情(就是不做任何事),并且没有返回任何值。
Objective-C
funcdoNothingA()->Void{}
funcdoNothingB()->(){}
funcdoNothingC(){}
doNothingA()用了更前卫的方式定义了一个空函数;而doNothingB()用了原始方式声明了空函数;doNothingC()则使用缺省方式声明空函数明,省略了返回值。
有趣的是,“Void”是“()”的typealias,也就是空元组。如果你记得这篇文章的开头,你就会想到我提到过元组可以包含零或多个类型。
选择你的发音
人们如何发出单词“tuple”的音有很大的争议。有些人喜欢说“Two-pull”,而其他人说:“Tup-pl”,而疯狂的人说:“Choo-pl”。无论您喜欢哪一种,准备把它说出来吧。