Louis Lac
Louis Lac

Reputation: 6426

Swift: Can't unwrap an optional inside a loop

I can't understand why unwrapping an optional value is possible in this case:

let name: String? = "Toto"
guard let name = name else { fatalError() }
print(name)

but not when this snippet is wrapped in a for-loop:

for _ in 0..<100 {
  let name: String? = "Toto"
  guard let name = name else { fatalError() }
  print(name)
}

I got the error "Definition conflicts with previous value".

Using Swift 5 in Xcode 11.0.

Upvotes: 1

Views: 293

Answers (1)

Martin R
Martin R

Reputation: 539955

As explained in Why isn't guard let foo = foo valid?,

let name: String? = "Toto"
guard let name = name else { fatalError() }

is not valid because guard does not introduce a new scope, and you cannot have two variables with the same name in the same scope.

That this compiles on the file level (i.e. in “main.swift”) is a bug. Apparently the variable bound via guard hides the other variable of the same name, regardless of the type and the order in which they are declared:

let aName = "Toto"
guard let aName = Int("123") else { fatalError() }
print(aName) // 123

guard let bName = Int("123") else { fatalError() }
let bName = "Toto"
print(bName) // 123

This bug has been reported as SR-1804 No compiler error for redeclaration of variable bound by guard.

Upvotes: 4

Related Questions