0

I am doing this in Playground, but I am not getting any error. Am I not recreating constant range? Is it happening in 2 different scopes? What's happening in the background that makes this not an error?

if let range = add1.rangeOfString(", ") {
    print(add1.substringToIndex(range.startIndex))
    print (range)
}

if let range = add1.rangeOfString(", ") {
    print(add1.substringToIndex(range.startIndex))
    print (range)
}
mfaani
  • 33,269
  • 19
  • 164
  • 293
  • *Conditional binding enables you to apply a cast, test the resulting optional, and then bind unwrapped values to a local variable*. See [here](http://www.informit.com/articles/article.aspx?p=2469047&seqNum=2) – mfaani Aug 29 '16 at 22:32

1 Answers1

3

Variables introduced with Optional binding of if-let is local after the let-clause till the end of true-case code block.

So, yes. Your two range reside in 2 different scopes.

(guard-let is another thing.)

OOPer
  • 47,149
  • 6
  • 107
  • 142
  • **1)** Can you explain why is it created that way? I couldn't find anything on Apple documentation. What's the underlying mechanism for this? **2)** And as a tangential question does. Is statement in the `{}` basically a completion handler? – mfaani Aug 29 '16 at 22:29
  • 1
    @Honey, 1) if-let is a combination of non-nil checking and declaring non-nil (unwrapped) variables. Something similar to `if something != nil {let unwrappedSomething = something!;...}`. The introduced variable should be in the context where `something != nil`. But, that's true, Apple's documentation lacks detailed description of many important features of Swift. – OOPer Aug 29 '16 at 22:46
  • 1
    @Honey, 2) `{}` notation bound with `if`, `while`, `do`... are called "code block". It bundles some amount of executable statements, and also introduces new scope for local variables. `{}` in a context of "expression" is called "closure expression" (or "closure literal", many call it simply "closure"), which you are calling "completion handler". "Closure"s can be stored in variables, passed to methods, but "code block" is a syntactic thing which cannot be separated from `if` (or some others). – OOPer Aug 29 '16 at 22:58
  • Thanks. I was aware of the non-nil and (finally understood after months) closure sytanx which made me observant of the `{}` but your clarifications made it much better. – mfaani Aug 29 '16 at 23:04
  • I even added this line: `let range = "11" `into the if-let *code block* and still didn't get any error. Why? – mfaani Aug 30 '16 at 14:16
  • 1
    In Swift, local declaration in a code block can "shadow" outer declarations. For example, `do {let a = 1; do {let a = "c"; do {let a = 0..<2}}}` is valid. Optional binding is a sort of hidden block, so you can shadow the declarations. – OOPer Aug 30 '16 at 21:56