【问题标题】:Swift : missing argument label 'xxx' in callSwift:调用中缺少参数标签“xxx”
【发布时间】:2014-07-25 21:28:32
【问题描述】:
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")

为什么?如果我在 func 中放置了两个以上的 var,那么当我调用这个 func 时我需要写 var name 而不是第一个 var
真的很麻烦,iBook Swift 教程里也没看到任何解释。

【问题讨论】:

  • 你的函数名是“say”,但你正在调用sayHello??
  • 我见过这个问题,但它没有解决我的问题
  • 这是一种方法吗? (在类范围内的函数?)

标签: ios swift


【解决方案1】:

一个可能的原因是它实际上是一种方法。方法很狡猾,它们看起来就像普通函数,但它们的行为方式不同,让我们看一下:

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)

这是方法行为设计的一部分

苹果文档:

具体来说,Swift 默认为方法中的第一个参数名称提供本地参数名称,并默认为第二个和后续参数名称提供本地和外部参数名称。此约定与您在编写 Objective-C 方法时熟悉的典型命名和调用约定相匹配,并且无需限定参数名称即可进行富有表现力的方法调用。

注意自动完成:

【讨论】:

  • 有趣的是,如果不为 Playground 中的第二个参数提供名称,它似乎工作得很好!
  • @user1107173 - 这是因为它超出了类的上下文。如果你把它放在一个类中,它会提供第二个参数的名称。游乐场与它没有任何关系:)
  • 这在 Swift 2.1 中不再适用。除了特殊的init 方法之外,函数和方法现在共享完全相同的参数标签语义。见this answer
【解决方案2】:

这只是Objective-C语言的影响。调用方法时,方法的第一个参数不需要显式标记(如在 Objective-C 中,它实际上是由方法名称“标记”的)。但是,所有以下参数都需要一个名称来识别它们。它们还可以采用(可选)本地名称以在方法本身内部使用(请参阅上面 cmets 中的 Jiaaro 链接)。

【讨论】:

  • 我觉得与其说“不需要显式标记”,不如说“不能被标记”,因为在那里添加标签会导致编译错误。
【解决方案3】:

简单:

错误的调用函数语法(在c/c++/java/c#中不一样)

不正确:

say("Henry")

正确:

say(name:"Henry")

PS:您必须始终!在值前添加“name function parameter”。

【讨论】:

  • 不是 2015 年。早期的 Swift 版本省略了第一个标签,就像在 Objective-C 中的方法和函数不需要任何人一样。你说的是比 OP 更新的 Swift 版本。
  • @iMalleus 是的)
【解决方案4】:

Swift 3.0 更新:

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

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

你的函数调用必须是这样的

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

如果你想有类似英文可读的函数标签但又不想改变输入参数名称,你可以在参数名称前添加标签,像这样

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

然后这样称呼它

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

【讨论】:

    【解决方案5】:

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

    以下是语言参考对函数的命名参数的说明(特别是未给出参数外部名称且参数没有默认值的参数)

    但是,这些参数名称仅在 函数本身,调用函数时不能使用。这些 各种参数名称称为局部参数名称,因为 它们只能在函数体内使用。

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

    【讨论】:

    • 其实没那么简单。如果您进一步阅读文档,有时内部名称会自动转换为外部名称,据我所知,它主要在类定义中,默认情况下需要第二个和以下标签。
    • @David 同意,我的回答涵盖了 func 实际上是一个函数的情况。洛根的回答涵盖了func 实际上是一种方法的情况。就个人而言,我不喜欢 Apple 的这种设计选择。无论上下文如何,函数/方法调用语法都应该是一致的。程序员可以使用# 语法强制使用参数名称作为样式问题。
    【解决方案6】:

    请在swift 3+中找小代码理解。

    func sumInt(a:Int,b:Int){
        print(a+b) // Displays 3 here
    }
    
    sumInt(a: 1, b: 2) // not like in other languages
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多