简体   繁体   中英

Assigning Closure to variable in Swift causes 'variable used before being initialized'

I have a problem with a closure that is meant to be created and then being executed within another function over the range of the 2D pixel raster of an image where it shall basically called like this: filter(i,j) and return a value based on its arguments. I thought this code should work but it complains that the closure variable I have created is not initialized. I guess that means that I did not gave it arguments, but I wont within this function as the data is known to the closure at the time when it interacts with the image. How can I setup a closure which does not care about initialization?

Thank you in advance :)

func processFilter(type:FilterType){
    var x = 0
    var y = 0
    //create cloure
    var closure:(i:Int, j:Int)->Int

    if(type == FilterType.MyFilter) {
        x = 1024
        y = 2048
        func filter(i:Int, j:Int)->Int {
            return i*j*x*y*4096
        }
        //compiler does not complain here...
        closure = filter
    }
    //other if statements with different closure definitions follow...


    //This call throws error: variable used before being initialized 
    let image = filterImage(closure)
}

You use the variable closure before the compiler is certain that it is initialized. You can solve this in 2 ways, depending on what you need:

  • Add an else -clause to your if and set closure to a default closure.
  • Make closure optional by defining it as var closure: ((i: Int, j: Int) -> Int)? and then you can check if it is optional before using it by using closure?(i, j) or if let filter = closure { filter(i, j)} .

Also, try to use better variable names such as filterClosure . closure on its own doesn't really say much.

The problem is that you define your closure as:

var closure:(i:Int, j:Int)->Int

Then you initialize it only if you enter the if

If not, that var is not initialized, hence the compiler warning

Possible solution:

func processFilter(type:FilterType){
    var x = 0
    var y = 0
    //create cloure
    var filterClosure:((i:Int, j:Int)->Int)?

    if(type == FilterType.MyFilter) {
        x = 1024
        y = 2048
        func filter(i:Int, j:Int)->Int {
            return i*j*x*y*4096
        }
        //compiler does not complain here...
        filterClosure = filter
    }
    //other if statements with different closure definitions follow...

    if let closure = filterClosure { 
        let image = filterImage(closure)
    }
}

Your closure is only initialized if the code enters your if block (ie if type == FilterType.MyFilter ). In the other case it is left uninitialized.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM