首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Swift 3系列:最佳实践

Swift 3系列:最佳实践
EN

Stack Overflow用户
提问于 2016-07-03 15:31:48
回答 2查看 16.6K关注 0票数 16

昨天我下载了Xcode 8.0测试版,然后下载了Swift 3。我做的第一件事就是尝试更新Swift 3的项目,我差点哭了。最严重的变化之一是(我认为) Swifts Range结构的新管理,特别是因为自动转换到当前Swift语法对范围没有任何作用。

Range分为RangeCountableRangeClosedRangeCountableClosedRange,当考虑现在使用范围时可能实现的内容时(尽管这是相当不必要的),这确实是有意义的。

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

在Swift 3中是否有使用ranges的最佳实践?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-07-03 16:04:01

其实很简单:

Closed...Range是由三个点( 0...10 )产生的。这包括下界和上界。相反的是一个非封闭范围,由0..<10产生,它不包括上限.

Countable...Range是一个类型的范围,您可以用有符号整数跨过它,它是由0...100..<10生成的。这些类型符合Sequence协议。

有几个例子:

代码语言:javascript
复制
0..<10 // CountableRange
0...Int.max // CountableClosedRange (this was not possible before Swift 3)

"A"..<"A" // Range, empty
"A"..."Z" // ClosedRange, because cannot stride through, only check if a character is in the bounds

根据需要,您可能应该让您的方法接受一个通用的Collection/Sequence

代码语言:javascript
复制
func test<C: Collection where C.Iterator.Element == Int>(s: C) {
    print(s.first)
}

也许你可以展示一下你对Range<Int>的一种用途

票数 15
EN

Stack Overflow用户

发布于 2016-07-04 05:26:25

闭域算子

封闭范围运算符(a...b)定义了从ab的范围,并包括值aba的值不能大于b

当迭代要在其中使用所有值的范围时,封闭范围运算符非常有用,例如使用for-in循环:

代码语言:javascript
复制
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)定义了从ab的范围,但不包括b。据说它是半开的,因为它包含它的第一个值,而不是它的最终值。与封闭范围运算符一样,a的值不得大于b。如果a的值等于b,则结果范围将为空。

当您使用基于零的列表(如数组)时,半开放范围特别有用,在这些列表中,最多计数(但不包括)列表的长度是有用的:

代码语言:javascript
复制
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

代码语言:javascript
复制
let myRange = 1...3
let myArray = ["a", "b", "c", "d", "e"]
myArray[myRange] // ["b", "c", "d"]

半开范围:a..<b

代码语言:javascript
复制
let myRange = 1..<3
let myArray = ["a", "b", "c", "d", "e"]
myArray[myRange] // ["b", "c"]

,这里是一个真实的SpriteKit示例,我不得不使用arc4Random进行转换,这实际上是所有SpriteKit项目中的一个。随机处理范围。

Swift 2

代码语言:javascript
复制
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

代码语言:javascript
复制
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>

迁移到Swift 3

RangeClosedRange不能迭代(它们不再是集合),因为仅仅是Comparable的值不能增加。CountableRangeCountableClosedRange需要从它们的绑定中提取Strideable,并且它们符合Collection,这样您就可以迭代它们。

票数 16
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38171488

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档