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



更新时间: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参数混淆,因为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,消除上面的混乱

可变参数必须是最后一个,根据你的情况,你可以这样输入:

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
}

最新更新