在开始初始化之前使用的swift 3变量

时间:2017-04-25 07:32:08

标签: swift

我的n变量存在问题。我不能在for循环中使用n。为什么?在for循环之前初始化n。请帮忙。

import Foundation

var n: Int
var t: Int

while(true){

    var tt = readLine()
    t = Int(tt!)!
    if (t==0){
        break
    }
    else if ( t < 0){
        n = t*(-1)
    }
    else if(t > 0){
        n = t
    }
    var arr : [[String]] = []
    for i in 0..<n*2{
        for y in 0..<n*2{
            arr[i][y] = "."
        }
    }
}

2 个答案:

答案 0 :(得分:4)

变量可以可以声明并且不会立即初始化,只要在首次使用之前保证初始化

错误比初看起来更微妙。实际上,您可以在不初始化属性的情况下声明属性,只要导致其首次使用的所有程序流都确定它的初始化。

问题在于ifelse ifelse if阻止:

var n: Int // declaration

// ...

if (t == 0) {
    break
}
else if (t < 0) {
    n = t*(-1)
}
else if (t > 0){
    n = t
}

// first use
for i in 0..<n*2 { /* ... */ }

Swift不能不推断这个块实际上是详尽无遗的,并且认为上述if语句都不可能存在,这在编译器看来会导致以下程序状态:

  • 程序流程尚未中断(break
  • n尚未实例化

然而,作为人类,我们知道上面的if - else if - else if块确实是详尽无遗的,并且可以通过简单地将最后的if else语句更改为简单的else语句来帮助编译器。

if (t == 0) {
    break
}
else if (t < 0) {
    n = t*(-1)
}
// if none of the above, t > 0
else {
    n = t
}

另一方面,不存在的数组元素arr[i][y] = "."的嵌套数组访问将导致运行时异常,但这是另一个问题。在其当前形式中,看起来嵌套循环的意图可以用嵌套数组实例化替换:

var arr = [[String]](repeating: [String](repeating: ".", count: 2*n), count: 2*n)

,或者

var arr = (0..<2*n).map { _ in [String](repeating: ".", count: 2*n) }

答案 1 :(得分:1)

变量n仅被声明,而不是初始化。

初始化变量:

var n: Int = 0
var t: Int = 0