1

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.

Louis Lac
  • 5,298
  • 1
  • 21
  • 36
  • 2
    Compare https://stackoverflow.com/questions/40353631/why-isnt-guard-let-foo-foo-valid – Martin R Oct 03 '19 at 21:27
  • Thanks, still don't understand why it isn't working in the first case as `name` is also redefined in te same scope. – Louis Lac Oct 03 '19 at 21:40
  • Where are you doing this? A Swift Playground? – vacawama Oct 03 '19 at 22:03
  • I tested it both in a Playground and in a real project (Mac application). – Louis Lac Oct 03 '19 at 22:08
  • Well, you've stumped me. It is odd behavior. Why you can't do it in your loop is well understood and explained by the link MartinR provided. As for first case, ???. The workaround in the loop is very easy of course, use a new variable name. – vacawama Oct 03 '19 at 22:20
  • Another strange issue that happens only in main (i.e. on the file level): https://bugs.swift.org/browse/SR-1804 – Martin R Oct 04 '19 at 06:09
  • @MartinR thank you, this is exactly the same issue. – Louis Lac Oct 04 '19 at 06:26

1 Answers1

4

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.

Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382