Swift:在调用中缺less参数标签“xxx”

func say(name:String, msg:String) { println("\(name) say \(msg)") } say("Henry","Hi,Swift") <---- error because missing argument label 'msg' in call 

我需要使用

  say("Henry",msg:"Hi,Swift") 

为什么? 如果我把超过两个var的func,所以我需要写var名​​称,而不是第一个var当我调用这个function
这真的很麻烦,我没有在iBook Swift教程中看到任何解释。

一个可能的原因是它实际上是一种方法。 方法非常鬼鬼祟祟,它们看起来就像普通函数一样,但是它们的行为不一样,让我们​​来看看这个:

 func funFunction(someArg: Int, someOtherArg: Int) { println("funFunction: \(someArg) : \(someOtherArg)") } // No external parameter funFunction(1, 4) func externalParamFunction(externalOne internalOne: Int, externalTwo internalTwo: Int) { println("externalParamFunction: \(internalOne) : \(internalTwo)") } // Requires external parameters externalParamFunction(externalOne: 1, externalTwo: 4) func externalInternalShared(#paramOne: Int, #paramTwo: Int) { println("externalInternalShared: \(paramOne) : \(paramTwo)") } // The '#' basically says, you want your internal and external names to be the same // Note that there's been an update in Swift 2 and the above function would have to be written as: func externalInternalShared(paramOne paramOne: Int, #paramTwo: Int) { print("externalInternalShared: \(paramOne) : \(paramTwo)") } externalInternalShared(paramOne: 1, paramTwo: 4) 

现在这里是有趣的部分,在类中声明一个函数,它不再是一个函数…这是一个方法

 class SomeClass { func someClassFunctionWithParamOne(paramOne: Int, paramTwo: Int) { println("someClassFunction: \(paramOne) : \(paramTwo)") } } var someInstance = SomeClass() someInstance.someClassFunctionWithParamOne(1, paramTwo: 4) 

这是方法行为devise的一部分

Apple文档:

具体来说,Swift默认在方法中给第一个参数名称一个本地参数名称,并且默认给出第二个和后续参数名称本地和外部参数名称。 这个约定匹配你在编写Objective-C方法时熟悉的典型的命名和调用约定,并且不需要限定你的参数名就可以进行expression式的方法调用。

注意自动完成: 在这里输入图像说明

这只是Objective-C语言的影响。 当调用方法时,方法的第一个参数不需要显式标记(如在Objective-C中,它被方法的名称有效地标记)。 但是,所有以下参数都需要一个名称来标识它们。 他们也可以在方法本身内部使用(可选的)本地名称(参见上面评论中的Jiaaro的链接)。

这是编译器中的一个怪癖。 函数(不是类的成员)和类方法在命名参数方面具有不同的默认行为。 这与Objective-C中命名参数的行为是一致的(但对于没有经验的Objective-C的新人来说,这是没有意义的)。

以下是关于函数命名参数的语言参考(特别是没有给出参数外部名称的参数,参数没有默认值)

但是,这些参数名称只能在函数本身中使用,在调用函数时不能使用。 这些types的参数名称称为本地参数名称,因为它们只能在函数体内使用。

有关类方法的信息,请参阅Logan的答案。

Swift 3.0更新:

在swift 3.0中,每个input具有一个参数名称的方法需要将该参数名称作为函数调用的一部分。 所以如果你这样定义函数

 func say(name:String, msg:String) { print("\(name) say \(msg)") } 

你的函数调用将是这样的

 self.say(name: "Henry",msg: "Hi,Swift") 

如果您希望英文具有可读的function标签,但不想更改input参数名称,则可以在参数名称的前面添加标签,如下所示

 func say(somethingBy name:String, whoIsActuallySaying msg:String) { print("\(name) say \(msg)") } 

然后像这样调用它

 self.say(somethingBy: "Henry",whoIsActuallySaying: "Hi,Swift")