为什么在Swift中的单数返回表达式中使用闭包速记命名变量必须是详尽的?
以下代码在Swift中是错误的为什么在Swift中的单数返回表达式中使用闭包速记命名变量必须是详尽的?,swift,swift3,closures,Swift,Swift3,Closures,以下代码在Swift中是错误的 func foo(closure: (Int, Int) -> Int) -> Int { return closure(1, 2) } print(foo(closure: {$0})) XCode提供的错误是无法将'(Int,Int)'类型的值转换为闭包结果类型“Int” 而下面的代码是完全正确的 func foo(closure: (Int, Int) -> Int) -> Int { return closur
func foo(closure: (Int, Int) -> Int) -> Int {
return closure(1, 2)
}
print(foo(closure: {$0}))
XCode提供的错误是无法将
'(Int,Int)'类型的值转换为闭包结果类型“Int”
而下面的代码是完全正确的
func foo(closure: (Int, Int) -> Int) -> Int {
return closure(1, 2)
}
print(foo(closure: {$0 + $1}))
似乎在闭包的参数由速记参数名引用的情况下,如果闭包的主体仅由返回表达式组成,则必须完全使用这些参数。为什么?你的“为什么”就像在问“为什么美国足球场有100码长?”因为这是规则。接受参数的匿名函数体必须明确确认所有参数。它可以通过以下三种方式中的任意一种实现:
- 使用
,$0
。。。符号$1
- 使用行中的
中的参数名称表示它们
- 在行中的中使用,显式丢弃它们
所以,让我们举一个比你简单得多的例子:
func f(_ ff:(Int)->(Void)) {}
如您所见,函数f
接受一个参数,这是一个接受一个参数的函数
那么,让我们尝试将一些匿名函数传递给f
这是合法的,因为我们在行中的中命名参数:
f {
myParam in
}
f {
_ in
}
这是合法的,因为我们使用$0
符号接受参数:
f {
$0
}
这是合法的,因为我们在
行中使用中的明确地丢弃参数:
f {
myParam in
}
f {
_ in
}
但这是不合法的:
f {
1 // error: contextual type for closure argument list expects 1 argument,
// which cannot be implicitly ignored
}
你的“为什么”就像在问“为什么美国足球场有100码长?”因为这是规则。接受参数的匿名函数体必须明确确认所有参数。它可以通过以下三种方式中的任意一种实现:
- 使用
$0
,$1
。。。符号
- 使用
行中的中的参数名称表示它们
在
行中的
中使用,显式丢弃它们
所以,让我们举一个比你简单得多的例子:
func f(_ ff:(Int)->(Void)) {}
如您所见,函数f
接受一个参数,这是一个接受一个参数的函数
那么,让我们尝试将一些匿名函数传递给f
这是合法的,因为我们在行中的中命名参数:
f {
myParam in
}
f {
_ in
}
这是合法的,因为我们使用$0
符号接受参数:
f {
$0
}
这是合法的,因为我们在
行中使用中的明确地丢弃参数:
f {
myParam in
}
f {
_ in
}
但这是不合法的:
f {
1 // error: contextual type for closure argument list expects 1 argument,
// which cannot be implicitly ignored
}
如果只使用$0
,则闭包参数假定为一个元组,而不是多个变量$0
、$1
等。因此,您应该能够通过提取该元组的第一个值来解决此问题:
print(foo(closure: {$0.0}))
如果只使用$0
,则闭包参数假定为一个元组,而不是多个变量$0
、$1
等。因此,您应该能够通过提取该元组的第一个值来解决此问题:
print(foo(closure: {$0.0}))
问题不是在问规则背后的原因,不是为了规则吗?我相信我们都希望斯威夫特的设计有道理;-)@CRD喜欢斯威夫特的很多规则,都是关于让你明确承认你知道自己在做什么。考虑<代码>重写< /代码>;它不添加任何内容(因为Objective-C不使用它),所以如果重写继承的成员,那么需要“为什么”呢?我想你误解了我的评论,可能不够清楚。事实上,我认为这更多地与Swift中类型推断的工作方式有关(参见@Palle的答案),这就是“为什么”——不是因为它是规则。类型推断不必以这种方式工作,一种不同的方法可以支持OP所期望的(但可能不是Swift所做的其他事情——这都是关于选择的)。OP提出了一个合理的问题。这个问题不是在问规则背后的原因,不是为了规则吗?我相信我们都希望斯威夫特的设计有道理;-)@CRD喜欢斯威夫特的很多规则,都是关于让你明确承认你知道自己在做什么。考虑<代码>重写< /代码>;它不添加任何内容(因为Objective-C不使用它),所以如果重写继承的成员,那么需要“为什么”呢?我想你误解了我的评论,可能不够清楚。事实上,我认为这更多地与Swift中类型推断的工作方式有关(参见@Palle的答案),这就是“为什么”——不是因为它是规则。类型推断不必以这种方式工作,一种不同的方法可以支持OP所期望的(但可能不是Swift所做的其他事情——这都是关于选择的)。OP提出了一个合理的问题。相关:。相关:。