无法将Swift 2.2 currying转换为未来的Swift格式

时间:2016-06-10 02:49:05

标签: swift currying

我有以下curried函数,我收到一个XCode警告, Curried函数语法将在未来版本的Swift中删除;使用单个参数列表,但建议的修复 - 它没有工作(它只是将参数组合成一个函数调用)。我正在尝试转换为新格式,但我不明白它是如何工作的。下面的beginFetchWithCompletionHandler函数要求handleDownload具有(data : NSData?, error : NSError?)的参数签名。

fetcher.beginFetchWithCompletionHandler(handleDownload)

我想传入一个整数,如下所示:

fetcher.beginFetchWithCompletionHandler(handleDownload(0))

以下curried函数完美运行(但会发出警告):

func handleDownload(iCount : Int)(data : NSData?, error : NSError?) -> Void {
    print(iCount)
    print(data!.length)
}

以下是我尝试过的内容,但是我收到了错误,"表达式解析为未使用的函数":

func handleDownload2(iCount:Int) -> (NSData?, NSError?) -> Void {
    return { (data: NSData?, error: NSError?) -> Void in {
            // received image
            print(iCount)
            print(data!.length)
        }
    }
}

2 个答案:

答案 0 :(得分:1)

内花括号错了,应该是:

func handleDownload2(iCount:Int) -> (NSData?, NSError?) -> Void {
    return { (data: NSData?, error: NSError?) -> Void in
        // received image
        print(iCount)
        print(data!.length)
    }
}

答案 1 :(得分:0)

接受的Swift Evolution提案SE-0002 - Removing currying func declaration syntax声明:

  

我们删除了对func声明中多个参数模式的支持,减少了func-signature的语法,只允许一个argument子句。出于迁移目的,可以转换使用currying声明语法的现有代码以显式返回闭包:

  // Before:
  func curried(x: Int)(y: String) -> Float {
    return Float(x) + Float(y)!
  }

  // After:
  func curried(x: Int) -> (String) -> Float {
    return {(y: String) -> Float in
      return Float(x) + Float(y)!
    }
  }

因此, Martin R 给出的答案是正确的:

func handleDownload2(iCount: Int) -> (NSData?, NSError?) -> Void {
    return { (data: NSData?, error: NSError?) -> Void in
        // received image
        print(iCount)
        print(data!.length)
    }
}

但请注意,您可以更简洁:

func handleDownload2(iCount: Int) -> (NSData?, NSError?) -> Void {
    return { (data, error) in
        // received image
        print(iCount)
        print(data!.length)
    }
}

此处,dataerror的类型由handleDownload2函数的返回类型隐式赋予:(NSData?, NSError?) -> Void

虽然我不建议将其用于可读性问题,但使用shorthand argument names可以使您的代码更加简洁:

func handleDownload2(iCount: Int) -> (NSData?, NSError?) -> Void {
    return {
        // received image
        print(iCount)
        print($0!.length)
    }
}

此外,我在使用闭包时尝试显式,因为它可以帮助我快速设置正确的返回类型:

func handleDownload2(iCount: Int) -> (NSData?, NSError?) -> Void {
    let innerBlock: (NSData?, NSError?) -> Void = { (data, error) in
        // received image
        print(iCount)
        print(data!.length)
    }
    return innerBlock
}