单区间做了增强,能够自动推断左右边界。
let esports = ["Hearthstone", "CS:GO", "League of Legends", "Super Smash Bros", "Overwatch", "Gigantic"]
esports[3...]
// returns ["Super Smash Bros", "Overwatch", "Gigantic"]
// In Swift 3, you had to write
esports[3..<esports.endIndex]
esports[...2]
// returns ["Hearthstone", "CS:GO", "League of Legends"]
esports[..<2]
// returns ["Hearthstone", "CS:GO"]
表达无穷序列
单边区间可以被认为是无穷大的区间,主要是利用 range 的可推断性,当需要使用 range 更远的元素时,能够自动去创建。
eg:
let uppercase = ["A", "B", "C", "D"]
// zip 操作符在处理的过程中,需要 range 进行不断增大,那么就会按照 RangeExpression 协议去访问 Range 中的元素。
let asciiCodes = zip(65..., uppercase)
print(Array(asciiCodes))
// prints [(65, "A"), (66, "B"), (67, "C"), (68, "D")]
这些都主要是利用了 Swift 中最新的 RangeExpression 协议。
在 swift 3 中,也是可以实现上述需求的。
let s = "Hello, World!"
let i = s.index(of: ",")!
// 使用 range 获取 subString
let greeting = s[s.startIndex..<i]
// 对集合进行切片
let greeting = s.prefix(upTo: i) // Hello
let withComma = s.prefix(through: i) // Hello
let location = s.suffix(from: i)
但是无论怎么看,Swift 4 的实现都要更加简洁易读,而且不容易出错。
模式匹配
range 在 swift 4 之前也是可以用在 pattern match 上的。 不过比较局限,需要使用 Int 等基础类型。
在 swift 4 中,还可以使用 Double 这种类型。
eg:
/// 模式匹配可以用在 double 这种无限细粒度划分的类型中。
func sentiment(_ rating: Double) -> String {
switch rating {
case ..<0.33:
return "A"
case ..<0.66:
return "B"
default:
return "C"
}
}
sentiment(0.5)
// returns B
RangeExpression
刚才已经看了 Range 在使用上的优势,那么 swift 4 中是如何实现的呢?
关于Range 新特性的讨论可以看这里: RangeExpression-Evolution