为什么我的Swift循环失败并显示错误“无法使用end< start”形成范围?

时间:2015-02-22 21:54:32

标签: swift for-loop runtime-error factors

我有一个for循环,用于检查数字是否是数字的因子,然后检查该因子是否为素数,然后将其添加到数组中。根据原始号码,我会收到错误

  

致命错误:无法与结尾形成范围<启动

这种情况几乎每次都会发生,但对于某些数字,它可以正常工作。我发现使用它的唯一数字是9,15和25。

以下是代码:

let num = 16 // or any Int
var primes = [Int]()

for i in 2...(num/2) {

    if ((num % i) == 0) {
        var isPrimeFactor = true

        for l in 2...i-1 {
            if ((i%l) == 0) {
                isPrimeFactor = false;
            }//end if
        }//end for

        if (isPrimeFactor == true) {
            primes.append(i)
        }//end if

    }//end if

}//end for

6 个答案:

答案 0 :(得分:38)

如果您需要具有动态值范围的循环,建议您使用stride(to:by:)代替..<...

如果..<,基本上...start_index > end_index将会崩溃。

例如:

let k = 5
for i in 10...k { print("i=\(i)") }
for i in 10..<k { print("i=\(i)") }

如何解决:

// swift 2.3
let k = 5
for i in 10.stride(to: k+1, by: 1) { print("i=\(i)") }
for i in 10.stride(to: k, by: 1) { print("i=\(i)") }

// swift 3.0
let k = 5
for i in stride(from: 10, through: k, by: 1) { print("i=\(i)") }
for i in stride(from: 10, to: k, by: 1) { print("i=\(i)") }

注意: 上方2个区块不会打印任何内容,但其中一个会在执行时崩溃。如果您想从更高号码转到更低号码,则需要将by参数更改为否定号码

参考:

答案 1 :(得分:9)

在第二个循环中,i将始终从2开始,这意味着您正在从2...1

循环

答案 2 :(得分:5)

ClosedRangeCountableRange都抛出此错误,除非start <= end。使用stride(from:to:by)的一个问题是它返回Strideable而不是Range,这与“在范围内”运算符~=不起作用。为了处理这些情况,我使用了一个扩展,该扩展为我提供了一个边界安全范围,其中无效范围变为空范围:

extension Int {
  func until(_ end: Int) -> CountableRange<Int> {
    return self <= end ? self..<end : self..<self
  }

  func through(_ end: Int) -> CountableRange<Int> {
    return self <= end ? self..<(end + 1) : self..<self
  }
}

两个都返回CountableRange,因此无效的through范围将变为空范围。 (注意:之所以选择名称until是因为此“安全”范围的行为与Kotlin / Android中的until范围相同)。

用法:

for i in 0.until(3) { /* do something */ }

let printRange = { (range: Range<Int>) -> Void in
  for i in range {
    print(i, terminator: " ")
  }
  print()
}
printRange(0.until(3))  // prints "0 1 2"
printRange(0.until(0))  // prints ""
printRange(3.until(0))  // prints ""
printRange(0.through(3))  // prints "0 1 2 3"
printRange(0.through(0))  // prints "0"
printRange(3.through(0))  // prints ""
print(0.until(1) ~= -1)  // prints "false"
print(0.until(1) ~= 0)  // prints "true"
print(0.until(1) ~= 1)  // prints "false"
print(0.until(0) ~= 0)  // prints "false"
print(1.until(0) ~= 0)  // prints "false"
print(0.through(1) ~= -1)  // prints "false"
print(0.through(1) ~= 0)  // prints "true"
print(0.through(1) ~= 1)  // prints "true"
print(0.through(0) ~= 0)  // prints "true"
print(1.through(0) ~= 0)  // prints "false"

答案 3 :(得分:0)

SWIIFT 4

最好的方法是使用步幅,如本文档页面所示: Generic Function stride(from:to:by:)

f1.check_vpn

,如果要包含LowerBound,请大步走过:Generic Function stride(from:through:by:)

答案 4 :(得分:0)

如果要使用upperBound

例如:for number in (0...highestPossibleNumber).reversed()

答案 5 :(得分:0)

使用简单的解决方案,您可以使用Stride和-

进行反向循环


func reverseArray(oldarray: [String]) -> [String] {
        var newArray = [String]()
        let len = oldarray.count
        for i in stride(from: len - 1, through: 0, by: -1)
        {    newArray.append(oldarray[i])
            print(i)
        }
        return newArray
    }

input :  print(reverseArray(oldarray: ["World", "Hello"]))

output : ["Hello", "World"]