1、Range
我们首先创建一个Range对象。
var x = 1...10
变量x表示了一个范围,范围的起始点为1,终点为10,并且包括1和10。由于Range实现了CollectionType协议,所以,如下所示,我们完全可以把Range视为一个集合。
x.count // 10 集合中包含的元素个数
x.contains(5) // ture 集合中包含元素5
x.contains(13) // false
正是由于Range实现了集合协议,所以它可以用于for循环结构。
for value in x {
print(value) // 输出 1,2,3,4,5,6,7,8,9,10
}
官方文档把Range成为索引集合,它擅长和集合类型配合来生成切片。例如,我们可以用range方便的在数组上做一个切片。
var array = [1,2,3,4,5,6,7,8,9]
array[2...5] // [3,4,5,6] 用range在数据上面做切片
注意 数组切片的类型为 ArraySlice<Int> ,切片后获得的只是原数组array的一个视图(与原数组共享同一段内存空间),并没有分配新的内存空间。
Range的定义还有其它的表达方式
var y = 1..<10
这种写法很“象形”,我们很容猜到这个写法的含义。1...10表达的是一个闭区间(包括1和10),1..<10表达的是一个半开区间(包括1但不包括10)。从集合的角度它等价于1...9。swift3把Range的定义完整化了,进一步提供另外两种表达式。
var z = 1<.<10 // 开区间,不包括1也不包括10
var u = 1<..10 // 半开区间,不包括1,但包括10
2、 IntervalType
swift3以后,我们将不再需要IntervalType了,swift将用Range的功能同时覆盖Range与Interval两种类型。当然这并不会影响我们学习Interval了。
Range目的用来表达一个集合(索引集合),而Interval重点描述一个区间,目的是为了实现模式匹配。我们可以举个例子看一下,比如我们想判断一个数字是否在一个Range内,我们可以这样来实现。
var range = Int.min...0
if range.contains(1) {
print("yes")
}
这个操作将会非常耗时,由于range是一个集合,所以这个比较的过程是一个集合元素逐一遍历的过程,实际上我们并不希望用这样的比较方式,我们更倾的应该是这样的比较。
var number = 1
if 1 >= Int.min && 1 <= 0
print("yes")
}
这样的比较过程相比于之前的遍历过程,那可谓“不知道高到哪里去了!”,而这就是Interval类型的存在的意义。Interval的设计目的是用于模式匹配。之前判断1是否在Int.min...0区间内,我们可以这样来实现。
var inteval = Int.min...0
range ~= 1 // false 模式匹配失败
操作符 ~= 我们成为模式匹配操作符,用于进行模式匹配,对于Interval而言这种模式匹配是通过“比较”来完成。现在我们可以完全理解Range与Interval的区别和联系了,当然从今往后它们就是一家啦。
Interval常常被用于switch case分支结构中,可以看另外一篇文章来了解switch中使用Intverval