Error using guard statement

Watching the "Building Better Apps with Value Types in Swift" WWDC video, and got to the part where he talks about the Sieve of Eratosthenes routine. Thought I'd plug it into a playground:


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
        }
    }
    return numbers.filter { $0 > 0 }
}


But on the line with the guard statement, I'm getting an error:


initializer for conditional binding must have Optional type, not 'Int'


Is this not allowed? I know an 'if let' has to have an optional, but I thought a 'guard' didn't need one?


Thanks.

If-let and guard-let have same restriction and functionality, check an optional value is not nil and declare a non-optional variable (I should write `constant`?).

Try using case-let.

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

Instead of


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


you should probably write


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


Guards are just an inverted if that checks that you actually escape (return, continue, break, throw) in the else part.

Then someone better let Apple know the syntax and usage of guard.. as this code was taken right from one of the slides from the WWDC session!

Yes, but the slides are not the truth. The nearest we can get the truth is the Swift Programming Language book and the compiler.


The condition of a guard can either be an expression, a case condition, or an optional binding. That is neither an expression nor a case condition, and optional bindings have to have an optional in the initializer part.


Do not expect the slides to be free from errors, especially for pre-release features such as these. If you try to compile the code from WWDC 2014 slides, there are many things that don't work in the release version of Xcode, even outside of Swift. Just try to compile the Metal shader code.

Hey Tsom,


Going over some of my code from earlier, I wondered if the head-banging I experienced was shared by others. Which is to say, I was in the same boat as you when I first built this code for the Sieve of Eratosthenes. I'm sure by now you've already found the solution, but still I wanted to offer my 2¢ worth.


func primes(n: Int) -> [Int]
{
    var numbers: Array<Int>    = Array(2..<n)
    for i in 0..<n-2
    {
        /
         Casting the i-th member of the numbers array as optional is necessary for "guard let ..." to work.
         */
        guard let prime = numbers[i] as Int? where prime > 0 else { continue }

        // stride changed too :-)
        for multiple in (2 * prime - 2).stride(to: n-2, by: prime)
        {
            numbers[multiple]   = 0
        }
    }
    return numbers.filter { $0 > 0 }
}

let myPrimes    = primes(50)
print("\(myPrimes)")
Error using guard statement
 
 
Q