【问题标题】:Assigning Closure to variable in Swift causes 'variable used before being initialized'在 Swift 中将闭包分配给变量会导致“变量在初始化之前使用”
【发布时间】:2015-06-28 13:19:44
【问题描述】:

我有一个闭包问题,该闭包旨在创建,然后在图像的 2D 像素光栅范围内的另一个函数中执行,它基本上应该像这样调用: filter(i,j) 并根据其参数返回一个值。 我认为这段代码应该可以工作,但它抱怨我创建的闭包变量没有初始化。我想这意味着我没有给它参数,但我不会在这个函数中,因为数据在它与图像交互时是已知的。如何设置一个不关心初始化的闭包?

提前谢谢你:)

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)
}

【问题讨论】:

    标签: ios swift closures


    【解决方案1】:

    在编译器确定它已初始化之前,您使用变量closure。您可以通过 2 种方式解决此问题,具体取决于您的需要:

    • 在 if 中添加 else 子句并将 closure 设置为默认闭包。
    • 通过将closure 定义为var closure: ((i: Int, j: Int) -> Int)? 使closure 成为可选,然后您可以使用closure?(i, j)if let filter = closure { filter(i, j)} 在使用它之前检查它是否是可选的。

    另外,尝试使用更好的变量名,例如filterClosureclosure 本身并没有说太多。

    【讨论】:

    • 感谢您的回答!我想将闭包设置为 nil 作为默认值,这也不被编译器接受,我想防止出现默认闭包。然而,使用可选项似乎是一种优雅的方式!变量名仅用于上面的示例,但实际上可能更有意义。
    【解决方案2】:

    问题在于您将闭包定义为:

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

    然后你初始化它只有当你输入if

    如果不是,则该 var 未初始化,因此编译器警告

    可能的解决方案:

    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)
        }
    }
    

    【讨论】:

    • 你的闭包现在返回一个可选类型,你应该使用括号。
    • 是的!谢谢,笔误!另外:我同意你命名闭包的建议filterClosure
    【解决方案3】:

    只有当代码进入您的if 块(即type == FilterType.MyFilter)时,您的闭包才会被初始化。在另一种情况下,它未初始化。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-23
      • 1970-01-01
      • 2023-04-02
      • 2017-05-06
      相关资源
      最近更新 更多