相同的名称(和签名)封闭& function:对于> 0参数不含糊,在调用时给出闭包优先级

时间:2016-08-11 10:16:23

标签: swift closures

同名和签名功能的优先规则&闭合

当定义一个闭包和一个具有相同名称的函数(比如foo)和签名时,看起来好像闭包在调用时看起来优先(看似含糊不清)foo

// Int -> () function
func foo(num: Int) { print("function \(num)")}

// Int -> () closure
let foo: (Int) -> () = { print("closure \($0)")}
/* or...
let foo = { (num: Int) in print("closure \(num)")} */

foo(1) // closure 1

如果我选择 - 单击这两个声明,它们会在相关声明标签下相互指向,不同之处在于它们被称为:

  

声明:func foo(num: Int)

     

相关声明:foo

     

...

     

声明:let foo: (Int) -> ()

     

相关声明:foo(_:)

如果我们尝试为零参数函数定义相同的双foo定义&关闭,我们得到一个编译时错误提示无效重新声明

// () -> () function
func foo() { print("function")}

// () -> () closure
let foo: () -> () = { print("closure")}
/* or...
let foo = { () in print("closure")} */
    /* error: invalid redeclaration of 'foo' */

问题:为什么上面的第一个案例被认为是非模糊的,为什么在调用foo(..)时闭包优先于函数(即,在重载决策中)是foo(...)

我无法找到任何官方文档(或现有的SO帖子)来解释这一点。

测试Swift 2.2 / Xcode 7.3和Swift 3.0-dev / IBM Sandbox(功能签名修改为func foo(_ num: Int) { ... })。

1 个答案:

答案 0 :(得分:0)

在Swift中,如果没有传递参数,则不能将变量和函数或闭包命名为相同的东西。虽然我们以不同的方式调用它们(foo代表变量和foo()代表函数。我们将得到无效的foo重新声明。编译器将变量视为没有像函数那样的参数。考虑其中一些案例:

@Override
protected void onProgressUpdate(String... values) {
      super.onProgressUpdate(values);

       //in the arrayList we add the messaged received from server
      arrayList.add(values[0]);
}
protected void onPostExecute (TCPClient result) {
     mAdapter = new MyCustomAdapter(this, arrayList);
     mList.setAdapter(mAdapter);
}

在这种情况下,class X { var value : Int = 0 func value() -> Int { return 1 } // Invalid redeclaration of 'value()' } let x = X() 是什么?它是x.value还是Int将类的方法视为闭包是合法且有用的。

如果我们变得更加棘手,那该怎么办呢?

() -> Int?

Swift应该使用属性class X { let value: () -> Int = { 2 } func value() -> Int { return 1 } // Invalid redeclaration of 'value()' } let x = X() let v = x.value() // ???? 然后调用它吗?或者它应该调用方法value 闭包是完全合法的属性。

但是,使用参数,你可以命名一个函数和一个变量/ Closure相同的东西,虽然我建议你不要。在这种情况下,您应该尝试将变量和函数命名为描述它们是什么和/或它们如何使您的代码更易被其他人读取。我建议将变量命名为

value()?

因为通过命名函数,当你的方法和变量名相同时,它将允许用户确切地知道你正在调用哪个函数用户可以知道他们正在传递什么参数。通过在调用下面的方法时命名。

class X {    
    // Int -> () function
    func foo(number num: Int) { print("function \(num)")}

    // Int -> () closure
    let foo: (Int) -> () = { print("closure \($0)")}
}

CMD + 点击它会指向您为其编写的确切方法或变量/闭包。

考虑前面的例子:

let x = X()
x.foo(number: 2)
x.foo(3)

尽管您调用了正确的方法或闭包。通过 cmd + 点击,它只会指向关闭。