你能覆盖闭包内的变量定义吗?

时间:2016-06-21 08:31:50

标签: swift scope closures

代码示例来自swift office document

let digitNames = [
    0: "Zero", 1: "One", 2: "Two",   3: "Three", 4: "Four",
    5: "Five", 6: "Six", 7: "Seven", 8: "Eight", 9: "Nine"
]
let numbers = [16, 58, 510]

let strings = numbers.map {
    (number) -> String in
    var number = number //What is this!
    var output = ""
    while number > 0 {
        output = digitNames[number % 10]! + output
        number /= 10
}    
    return output
}

我对封闭体内部的var number = number行感到非常困惑。你怎么能重新宣布"具有相同范围的变量?

1 个答案:

答案 0 :(得分:2)

作用域中定义的常量或变量可以使用相同的名称 作为外部范围中定义的另一个常量/变量。在这种情况下, 局部变量“隐藏”外部变量,但仅限于其定义之后。 新变量的初始值可以引用外部变量 同名。例如:

func foo() {
    let x = 5
    do {
        var x = x
        //      ^-- The value of the outer constant `x`
        //  ^------ The local variable x
        x += 1
        print(x) // 6
    }
    print(x) // 5
}

一个常见的用例是制作函数参数的“变量副本”:

func digitsum(n : Int) -> Int {
    var s = 0
    var n = n
    while n > 0 {
        s += n % 10
        n /= 10
    }
    return s
}

在你的闭包中也是如此:

let strings = numbers.map {
    (number) -> String in
    var number = number
    //           ^-- The number that the closure was called with
    //  ^----------- A local variable `number`
    var output = ""
    while number > 0 {
        output = digitNames[number % 10]! + output
        number /= 10
    }    
    return output
}

当然,您也可以为局部变量选择不同的名称。

在早期的Swift版本中,您可以声明一个函数参数 作为变量:

func digitsum(var n : Int) -> Int

但该功能在Swift 2.2中已弃用,将被删除 在Swift 3中。