Swift 3.0闭包表达式:如果variadic参数不在参数列表的最后位置怎么办?

时间:2016-09-17 16:00:42

标签: swift closures swift3 variadic

2016.09.19更新

在闭包表达式参数列表中的某些其他参数之前使用可变参数有一种棘手的间接方法,哈哈

let testClosure = { (scores: Int...) -> (_ name: String) -> String in
    return { name in
        return "Happy"
    }
}
let k = testClosure(1, 2, 3)("John")

我在bugs.swift.org中发现了一些相关问题: SR-2475 SR-494

原帖

根据document of Swift 3.0,对于闭包表达式,“如果命名variadic参数,则可以使用变量参数”(请参阅​​Closure Expresssion语法部分)。但是对于Swift 2.x,描述是“如果你将可变参数命名为并将其放在参数列表的最后位置”,则可以使用变量参数,在Swift 3.0文档中删除了边框部分,是否意味着variadic参数可以是闭包表达式的参数,即使它不在最后的位置?如果是这样,为什么以下代码无法成功编译?

let testClosure = { (scores: Int..., name: String) -> String in
    return "Happy"
}
let k = testClosure(1, 2, 3, "John") // Missing argument for parameter #2 in call

如果参数标签可以在调用中使用,我认为编译器可以成功编译上面的代码,但在Swift 3.0中,闭包表达式的参数标签被认为是无关的。

此外,Swift 3.0文档表明闭包表达式语法中的参数可以是in-out参数,但Swift 3.0表示闭包表达式语法可以使用常量参数,变量参数和inout参数。为什么Apple删除了常量参数,变量参数之类的描述,是因为在Swift 3.0中,参数不能是var

非常感谢你的帮助!

3 个答案:

答案 0 :(得分:0)

仍然在Swift3中,可变参数必须是签名中的最后一个参数,因为尽管在你的情况下可以推导出最后一个输入为String的参数,但在某些情况下不是,因为可变参数的无限扩展:

let foo = { (i:Int..., j: Int) -> Int  in
    return j
}
foo(1,2)

...在Swift 3.0中,参数不能变成

var参数在Swift3 SE-0003中删除,以避免与inout参数混淆,因为varinout参数都可以在函数内部分配,但是只有inout被反射回来。

 func doSomethingWithVar(var i: Int) {
    i = 2 // change visible inside function.
 }

 func doSomethingWithInout(inout i: Int) {
    i = 2 // change reflected back to caller.
 }

从参数列表中删除var,消除上面的混淆。

答案 1 :(得分:0)

Variadic参数必须是最后一个,根据您的情况,您可以输入:

let testClosure = { (_ name: String, scores: Int...) -> String in
    return "Happy"
}
let k = testClosure("John", 1, 2, 3) 

答案 2 :(得分:0)

您可以在Swift 3.0中创建一个func,其中variadic参数不是最后一个参数。例如......

func addButtons(buttons: UIButton..., completion: (() -> ())? = nil)

我相信这是因为variadic参数后面的参数被命名,因此func不会将下一个命名参数与更多可变参数混淆。

addButtons(buttons: button1, button2, button3) {
     //do completion stuff
}