为什么在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

以下代码在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 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提出了一个合理的问题。相关:。相关:。