更新时间: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 - 2475sr - 494
原始文章
根据Swift 3.0的文档,对于闭包表达式,"如果你命名了可变参数,就可以使用可变参数"(参见闭包表达式语法部分)。但对于斯威夫特来说。x,描述是"可变参数可以使用,如果你命名可变参数,并把它放在参数列表的最后",边界部分已在Swift 3.0文档中删除,这是否意味着可变参数可以是闭包表达式的参数,即使它不是在最后的地方?如果是,为什么下面的代码不能编译成功?
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参数。为什么苹果删除了常量参数、变量参数之类的描述,是因为Swift 3.0的参数不能是var
吗?
非常感谢你的帮助!
仍然在Swift3可变参数必须是签名中的最后一个参数,因为尽管在您的情况下,最后一个参数类型为String
可以推断,但由于可变参数的无限扩展,在某些情况下不能:
let foo = { (i:Int..., j: Int) -> Int in
return j
}
foo(1,2)
…在Swift 3.0中,参数不能是var?
var
参数在Swift3 SE-0003中被删除,以避免与inout
参数混淆,因为var
和inout
参数都可以在函数内部分配,但只有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
,消除上面的混乱
可变参数必须是最后一个,根据你的情况,你可以这样输入:
let testClosure = { (_ name: String, scores: Int...) -> String in
return "Happy"
}
let k = testClosure("John", 1, 2, 3)
你可以在Swift 3.0中创建一个变量形参不是最后一个参数的函数。例如…
func addButtons(buttons: UIButton..., completion: (() -> ())? = nil)
我认为这是因为变量形参后面的形参被命名了,所以func不会将下一个命名实参与更多的变量形参混淆。
addButtons(buttons: button1, button2, button3) {
//do completion stuff
}