Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

guard let in swift 2.0 playground gets error about optional binding... why?

Tags:

let

xcode

ios

swift

I was watching this video. At 9:40 or so there is some sample code on the screen that looks like the code below:

//Sieve of Eratosthenes, as seen in WWDC 2015

func primes(n: Int) -> [Int] {
var numbers = [Int](2..<n)
for i in 0..<n-2 {
    guard let prime = numbers[i] where prime > 0 else { continue }
      for multiple in stride(from: 2 * prime-2, to: n-2, by: prime) {
        numbers[multiple] = 0
        print("\"numbers[i]")
      }

    }
return numbers.filter { $0 > 0 }
}

When I type that into an Xcode playground, I get the following error:

Initializer for conditional binding must have Optional type, not 'Int.'

Why is that?

like image 702
Dave Kliman Avatar asked Oct 31 '22 12:10

Dave Kliman


1 Answers

The "problem" here is the statement guard let prime = numbers[i]. The compiler complains about it because the guard let syntax expects numbers[i] to be an Optional which it can conditionally unwrap. But it is not an optional, you are always able to retrieve the i-th Int out of the array.

To fix it simply write

let prime = numbers[i]
guard prime > 0 else { continue }

The correct usage of the stride then looks like the following (after a long search in the comments):

for multiple in (2*prime-2).stride(to: n-2, by: 2*prime-2) {

Then final piece is then to change the print:

print("\(numbers[i])")
like image 125
luk2302 Avatar answered Nov 09 '22 09:11

luk2302