为什么重新声明 output
在此if语句中不会产生错误?
let output = 0
if counter < message.count {
let output = counter //This should throw an error, right?
counter += 1
} ...
当尝试更改output
的值而不是重新声明时,if语句中的范围知道此处已经证明output
:
let output = 0
if counter < message.count {
output = counter //ERROR: Cannot assign to value: 'output' is a 'let' constant
counter += 1
} ...
答案 0 :(得分:3)
没有错误,因为在闭包内声明一个变量是完全合法的,该变量具有在闭包之外声明的变量的相同名称。它会影响&#34;外部声明的变量&#34;。
如果您的示例代码位于class
内,您仍然可以访问&#34;外部声明的变量&#34;使用self
:
class Foo {
let output = 0
func baa() {
let output = 1
print(output)
print(self.output)
}
}
使用此:
let foo = Foo()
foo.baa()
打印:
1
0
答案 1 :(得分:1)
let output = counter
在if
语句的范围内声明一个新变量(输出),该变量与在外部声明的output
变量无关。
修改强>
下面的代码摘录说明output
变量虽然名称不同,但并不相同。更改的值是本地output
变量之一,而不是外部变量。
var message = [String]()
let output = 2
var counter = -1
if counter < message.count {
let output = counter //This should throw an error, right?
print("local output value is:\(output)") // here the local output value is -1 not 2.
counter += 1
}
答案 2 :(得分:1)
第一个例子是variable shadowing的情况。当代码具有多个范围块时会发生这种情况。在第一个例子中:
let output = 0 //outer scope block
if counter < message.count {
let output = counter //inner scope block
counter += 1
} ...
在内部范围块中,新的输出&#39;已经宣布常数为&#39; let&#39;关键词。该输出常数仅在该范围内有效,如果&#39;块。它碰巧使用与&#34;上面声明的名称相同的名称;如果&#34;声明。这是可变阴影。
对于第二个例子:
let output = 0
if counter < message.count {
output = counter //ERROR: Cannot assign to value: 'output' is a 'let' constant
counter += 1
} ...
错误正在发生,因为用&#39; let&#39;定义了一些内容。使它成为一个常数。它无法改变。在这种情况下,只有一个输出&#39;不变。它在if语句之上声明,它是一个常量。因此,一旦赋值,就无法更改。
所以,在第一个例子中,有2&#34;输出&#34;常数,其中一个仅在&#34;中有效;如果&#34;声明。在第二个例子中,只有1&#34;输出&#34;不变。
答案 3 :(得分:0)
大括号构成范围。在内部范围中,从外部范围掩盖变量名称总是合法的。
let output = // ... [A]
[class, func, if, for, do, etc.] {
let output = // ... [B, overshadows A]
// *
}
在某种意义上,您已经完成了自我限制,因为*
点的代码现在可能无法引用output
A;它被output
B黯然失色。但这并非违法。相反,这是一件重要的事情,能够做到这一点,并且不允许这样做会很愚蠢。