Overriding variables in functions

Why does n't redeclaringoutput

inside this if-statement generate an error?

let output = 0
if counter < message.count {
    let output = counter //This should throw an error, right?
    counter += 1
} ...

      

The scope inside the if statement is aware of output

, as shown here, when trying to change the value output

instead of re-declaring:

let output = 0
    if counter < message.count {
        output = counter //ERROR: Cannot assign to value: 'output' is a 'let' constant
        counter += 1
    } ...

      

+3


source to share


4 answers


There is no error because it is perfectly legal to declare a variable inside a closure with the same variable name that was declared outside the closure. It shadows the "external declared variable".

If your sample code is inside class

, you can still access the "external declared variable" with self

:

class Foo {
    let output = 0
    func baa() {
        let output = 1
        print(output)
        print(self.output)
    }
}

      

Using this:



let foo = Foo()
foo.baa()

      

prints:

1
0

      

+3


source


let output = counter

declares a new variable (output) in the statement scope if

that has nothing to do with the variable output

declared outside.

Edit



The code snippet below shows that the variables are output

not the same despite their name. The changed value is a local variable output

, not an external one.

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
}

      

+1


source


The first example is the case of tracking variables . This happens when the code has multiple blocks of blocks. In the first example:

let output = 0  //outer scope block
if counter < message.count {
    let output = counter //inner scope block
    counter += 1
} ...

      

In the internal visibility block, a new constant 'output' has been declared with the keyword 'let'. This output constant is only valid in this if block. This means that the same name is used as the "if" statement above. This is variable shading.

For the second example:

let output = 0
if counter < message.count {
    output = counter //ERROR: Cannot assign to value: 'output' is a 'let' constant
    counter += 1
} ...

      

The error occurs because defining something with "let" makes it a constant. It cannot be changed. In this case, there is only one "output" constant. It was declared above the if statement, and it is a constant. Thus, it cannot be changed after it has been assigned a value.

So in the first example there are 2 "output" constants, one of which is only valid in the if statement. In the second example, there is only 1 "output" constant.

+1


source


Curly brackets represent the scope. In the inner scope, it is always right to obscure the variable name from the outer scope.

let output = // ... [A]
[class, func, if, for, do, etc.] {
    let output = // ... [B, overshadows A]
    // *
} 

      

You've done a self-limiting thing, in a sense, in that the code at the point *

can no longer reference output

A; it is overshadowed by output

B. But this is not illegal. On the contrary, it is an important thing to do and it would be foolish to forbid it.

0


source







All Articles