jjzjj

swift 3 范围 : Best Practices

coder 2023-07-15 原文

我昨天下载了 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/

有关swift 3 范围 : Best Practices的更多相关文章

  1. ruby - 触发器 ruby​​ 中 3 点范围运算符和 2 点范围运算符的区别 - 2

    请帮助我理解范围运算符...和..之间的区别,作为Ruby中使用的“触发器”。这是PragmaticProgrammersguidetoRuby中的一个示例:a=(11..20).collect{|i|(i%4==0)..(i%3==0)?i:nil}返回:[nil,12,nil,nil,nil,16,17,18,nil,20]还有:a=(11..20).collect{|i|(i%4==0)...(i%3==0)?i:nil}返回:[nil,12,13,14,15,16,17,18,nil,20] 最佳答案 触发器(又名f/f)是

  2. ruby-on-rails - 相关表上的范围为 "WHERE ... LIKE" - 2

    我正在尝试从Postgresql表(table1)中获取数据,该表由另一个相关表(property)的字段(table2)过滤。在纯SQL中,我会这样编写查询:SELECT*FROMtable1JOINtable2USING(table2_id)WHEREtable2.propertyLIKE'query%'这工作正常:scope:my_scope,->(query){includes(:table2).where("table2.property":query)}但我真正需要的是使用LIKE运算符进行过滤,而不是严格相等。然而,这是行不通的:scope:my_scope,->(que

  3. ruby - 当使用::指定模块时,为什么 Ruby 不在更高范围内查找类? - 2

    我刚刚被困在这个问题上一段时间了。以这个基地为例:moduleTopclassTestendmoduleFooendend稍后,我可以通过这样做在Foo中定义扩展Test的类:moduleTopmoduleFooclassSomeTest但是,如果我尝试通过使用::指定模块来最小化缩进:moduleTop::FooclassFailure这失败了:NameError:uninitializedconstantTop::Foo::Test这是一个错误,还是仅仅是Ruby解析变量名的方式的逻辑结果? 最佳答案 Isthisabug,or

  4. Ruby 从大范围中获取第 n 个项目 - 2

    假设我有这个范围:("aaaaa".."zzzzz")如何在不事先/每次生成整个项目的情况下从范围中获取第N个项目? 最佳答案 一种快速简便的方法:("aaaaa".."zzzzz").first(42).last#==>"aaabp"如果出于某种原因你不得不一遍又一遍地这样做,或者如果你需要避免为前N个元素构建中间数组,你可以这样写:moduleEnumerabledefskip(n)returnto_enum:skip,nunlessblock_given?each_with_indexdo|item,index|yieldit

  5. sql - 查询忽略时间戳日期的时间范围 - 2

    我正在尝试查询我的Rails数据库(Postgres)中的购买表,我想查询时间范围。例如,我想知道在所有日期的下午2点到3点之间进行了多少次购买。此表中有一个created_at列,但我不知道如何在不搜索特定日期的情况下完成此操作。我试过:Purchases.where("created_atBETWEEN?and?",Time.now-1.hour,Time.now)但这最终只会搜索今天与那些时间的日期。 最佳答案 您需要使用PostgreSQL'sdate_part/extractfunction从created_at中提取小时

  6. Ruby 日期参数超出范围 - 2

    我正在尝试使用在我的代码中是动态的Time.local来安排时间。在每个月的第一天,我传递的值是Time.local(2009,9,-1,0)。在PHP中,这会将时间设置为上个月的最后一天。在ruby​​中,我只是得到“ArgumentError:参数超出范围”。是我用错了方法还是什么?谢谢。 最佳答案 您应该使用DateTime类而不是Time。(您可能需要先require'date'并安装activesupportgem。)它比Time更通用,并且可以用DateTime.civil(2009,9-1,-1,0)做你想做的事。为天

  7. ruby-on-rails - ruby 范围 : operators in case statement - 2

    我想检查my_number是否在某个范围内,包括较高的值。在IF语句中我会简单地使用“x>100&&x但是我应该在Ruby案例中做什么(开关)?使用:casemy_numberwhenmy_number不起作用。备注:标准范围不包括my_number恰好为500的情况,并且我不想添加第二个“when”,因为我必须编写双重内容casemy_number#between100and500when100..500puts"Correct,dosomething"when500puts"Correct,dosomethingagain"end 最佳答案

  8. Ruby - 从变量中获取位范围 - 2

    我有一个变量,想从该变量中获取一定范围的位。我想要最干净的方式来做到这一点。如果x=19767并且我想要bit3-bit8(从右边开始):100110100110111在二进制中是19767。我想要括号100110(100110)111中的部分,所以答案是38。用Ruby实现以下功能的最简单/最干净/最优雅的方法是什么?bit_range(orig_num,first_bit,last_bit)附言。计算强度较低的答案可加分。 最佳答案 19767.to_s(2)[-9..-4].to_i(2)或19767>>3&0x3f更新:从头

  9. ruby - 使用 Class.new 时访问外部范围 - 2

    是否有可能以某种方式访问​​Class.new范围内的a?a=5Class.new{defb;aend}.new.b#NameError:undefinedlocalvariableormethod`a'for#:0x007fa8b15e9af0>#:in`b' 最佳答案 即使@MarekLipka的回答是正确的——改变变量范围总是有风险的。这是可行的,因为每个block都带有创建它的上下文,因此您的局部变量a突然变得不那么局部了——它变成了一个“隐藏的”全局变量:a=5object=Class.new{define_method(

  10. ruby - private、protected 和 public 的范围 - 2

    在Ruby类定义中,private关键字在以下场景中的作用域是什么:classFoodefbar_publicputs"public"endprivatedefbar_privateputs"private"enddefbar_public_2puts"anotherpublic"endendprivate是否只作用于bar_private?还是在bar_public_2上? 最佳答案 在您的例子中,bar_private和bar_public_2都是私有(private)的。那是因为这两种方法都在private关键字的“范围内”。

随机推荐