Simple Swift question. I can make my label visible to the caller and give a label variable name that is used internal to my function. ( thats my understanding 😁)
But I noticed if I declare a variable with the same internal name within the function, the compiler does not create an error. It just replaces it after the declearation without errors. For instance, I would have expected internalTest:Float and internalTest:Array to create a compiler warning or error. Probably should be an error.
func test(externalTest internalTest:Float) {
print("test =\(internalTest)")
var internalTest:[Int] = [1,2,3] //Conflicts with method parameter?
internalTest.append(4)
print("test =\(internalTest)")
}
//Call test method
test(externalTest:1.0)
Playground prints:
internalTest = 1.0
internalTest = [1, 2, 3, 4]
No, by design it's not an error. It's called variable "shadowing".
Shadowing, when it does not produce compile errors, can certainly be a source of bugs. OTOH it's a convenient way of avoiding having think of new names for temporary variables, so it's a convenient pattern once you're used to it. Originally, shadowing was only allowed in some contexts, such as shadowing an instance property with a local variable, but it's gradually become available everywhere.
The best argument for it is in optional binding:
func test(externalTest internalTest:Float?) {
if let internalTest = internalTest {
… }
}This "removes" the optionality but keeps the semantic connection with the parameter. You can also use it when you want modify a parameter variable locally within the function:
func test(externalTest internalTest:Float) {
var internalTest = internalTest
while internalTest > 0 {
…
internalTest -= …
}
}Again, this helps clarify that you're "really" iterating on the incoming parameter.
Once you're aware of the shadowing pattern and get used to using it, you'll find you rarely make a mistake with unintended shadowing.