【发布时间】:2015-10-27 03:51:03
【问题描述】:
这是一个 Swift 函数,它接受两个整数和一个三参数函数,并调用传入的函数。
func p(x:Int, _ y:Int, _ f: (Int, Int, Int) -> ()) {
f(x, y, 0)
}
我可以使用尾随闭包语法和速记参数名称来调用它,没问题:
> p(1, 2) {print($0 + $1 + $2)}
3
按预期工作。但是在Foundation库中,有一个字符串方法叫enumerateSubstringsInRange,定义如下:
func enumerateSubstringsInRange(
_ range: Range<Index>,
options opts: NSStringEnumerationOptions,
_ body: (substring: String?,
substringRange: Range<Index>,
enclosingRange: Range<Index>,
inout Bool) -> ())
好的,这很简单:该函数接受三个参数,最后一个是四参数函数。就像我的第一个例子一样!或者我是这么想的......
我可以将此函数与尾随闭包语法一起使用,但我不能使用速记参数名称!我不知道为什么。这是我尝试过的:
let s = "a b c"
"a b c".enumerateSubstringsInRange(s.characters.indices, options: .ByWords) {(w,_,_,_) in print(w!)}
a
b
c
一切都好;我只是想打印出匹配的单词,一次一个。当我将闭包指定为 `{(w,,,_) in print(w!)}` 时,这很有效。但是,当我尝试使用速记参数语法编写闭包时,灾难:
> "a b c".enumerateSubstringsInRange(s.characters.indices, options: .ByWords) {print($0!)}
repl.swift:9:86: error: cannot force unwrap value of non-optional type '(substring: String?, substringRange: Range<Index>, enclosingRange: Range<Index>, inout Bool)' (aka '(substring: Optional<String>, substringRange: Range<String.CharacterView.Index>, enclosingRange: Range<String.CharacterView.Index>, inout Bool)')
那我做错了什么?!错误消息似乎表明闭包参数$0 是args 的整个元组。确实,当我尝试这样做时,似乎确实如此!
>"a b c".enumerateSubstringsInRange(s.characters.indices, options: .ByWords) {print($0.0!)}
a
b
c
所以我非常困惑。为什么在第一种情况下(我的函数p,参数被理解为$0、$1 等,但在第二种情况下,所有参数都汇总成一个元组?或者是吗?FWIW ,我找到了 enumerateSubstringsInRange here 的签名。
【问题讨论】: