swift 3 范围 : Best Practices

标签 swift swift3

我昨天下载了 Xcode 8.0 beta,随后下载了 Swift 3。我做的第一件事就是尝试为 Swift 3 更新我的项目,我差点哭了。最严重的变化之一是(在我看来)Swifts 的新管理层 Range struct,特别是因为自动转换为当前 Swift 语法不会对范围做任何事情。

Range分为Range , CountableRange , ClosedRangeCountableClosedRange在考虑使用范围时现在可能发生的事情时,这确实有意义(尽管这在很大程度上是不必要的)。

但是:我有很多接受 Range<Int> 的函数作为参数或返回 Range<Int> .问题是:我通过 0..<5 调用了这些函数例如或 0...4 (因为它有时在语义上更具表现力)。当然,我可以简单地调整这些类型的东西。但为什么不是所有这些范围类型都有一个通用接口(interface)呢?我必须为这些范围类型中的每一个重载每个函数,并且它每次都会执行完全相同的操作。

在 Swift 3 中使用范围是否有任何最佳实践?

最佳答案

近距离运算符(operator)

闭域运算符 (a...b)定义从 a 开始的范围至 b , 并包含值 ab . a 的值不得大于 b .

封闭范围运算符在迭代您希望使用所有值的范围时很有用,例如使用 for-in 循环:

for index in 1...5 {
    print("\(index) times 5 is \(index * 5)")
}
// 1 times 5 is 5
// 2 times 5 is 10
// 3 times 5 is 15
// 4 times 5 is 20
// 5 times 5 is 25

半开域算子

半开范围运算符 (a..<b)定义从 a 开始的范围至 b , 但不包括 b .据说它是半开的,因为它包含它的第一个值,但不包含它的最终值。与封闭范围运算符一样,a 的值不得大于 b .如果 a 的值等于b ,那么结果范围将为空。

当您使用从零开始的列表(例如数组)时,半开范围特别有用,在这种情况下,计数到(但不包括)列表的长度非常有用:

let names = ["Anna", "Alex", "Brian", "Jack"]
let count = names.count
for i in 0..<count {
    print("Person \(i + 1) is called \(names[i])")
}
// Person 1 is called Anna
// Person 2 is called Alex
// Person 3 is called Brian
// Person 4 is called Jack

请注意,该数组包含四个项目,但 0..<count只算到 3 (数组中最后一项的索引),因为它是一个半开范围。

封闭范围:a...b

let myRange = 1...3
let myArray = ["a", "b", "c", "d", "e"]
myArray[myRange] // ["b", "c", "d"]

半开范围:a..<b

let myRange = 1..<3
let myArray = ["a", "b", "c", "d", "e"]
myArray[myRange] // ["b", "c"]

Here's a real-world SpriteKit example I had to convert using arc4Random which is in virtually all SpriteKit projects. Random often deals with ranges.

swift 2

Tools.swift

func randomInRange(_ range: Range<Int>) -> Int {
    let count = UInt32(range.upperBound - range.lowerBound)
    return  Int(arc4random_uniform(count)) + range.lowerBound
}

GameScene.swift

let gap = CGFloat(randomInRange(StackGapMinWidth...maxGap))

swift 3

Tools.swift

func randomInRange(range: ClosedRange<Int>) -> Int {
    let count = UInt32(range.upperBound - range.lowerBound)
    return  Int(arc4random_uniform(count)) + range.lowerBound
}

GameScene.swift

let gap = CGFloat(randomInRange(range: StackGapMinWidth...maxGap))

所以如果 randomInRange()在给定范围内计算一个随机数,包括上限,那么它应该定义为ClosedRange<Bound>

Migrating to Swift 3

RangeClosedRange不能迭代(它们不再是集合),因为一个值仅仅是 Comparable不能递增。 CountableRangeCountableClosedRange需要 Strideable从他们的界限,他们符合 Collection以便您可以遍历它们。

关于 swift 3 范围 : Best Practices,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38171488/

相关文章:

ios - 如何更改 UIGraphicsGetCurrentContext 的 fillColor?

ios - CMMotionActivityManager 授权状态

swift - iOS9 Swift 文件创建 NSFileManager.createDirectoryAtPath 与 NSURL

arrays - 在 Swift 中拆分具有多个字符的字符串

ios - Swift 3动画问题

uikit - CGRectMake、CGPointMake、CGSizeMake、CGRectZero、CGPointZero 在 Swift 中不可用

swift - AFNETWORK单例类,Swift

ios - 在 C 回调中快速转换 UnsafeMutablePointer<Void>

ios - UIPickerView 只显示问号

ios - 如何从 Swift 3 中的 UIWebview 中的链接打开另一个 View ?