Swift: отсутствует метка аргумента «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") 

Зачем ? Если я помещаю более двух переменных в func, поэтому мне нужно написать имя var вместо первого var, когда я вызываю эту функцию
Это действительно проблема, и я не вижу объяснений в учебнике 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) 

Это часть дизайна поведения для методов

Apple Docs:

В частности, Swift дает первое имя параметра в методе имя локального параметра по умолчанию и дает по умолчанию второй и последующий имена параметров как локальные, так и внешние имена параметров. Это соглашение соответствует типичному соглашению об именах и вызовах, с которым вы будете знакомы, при написании методов Objective-C, а также для экспресс-вызовов методов без необходимости определять имена параметров.

Обратите внимание на автозаполнение: введите описание изображения здесь

Это просто влияние языка Objective-C. При вызове метода первый параметр метода не должен быть явно помечен (как в Objective-C, он эффективно «помечен» именем метода). Однако всем следующим параметрам требуется имя для их идентификации. Они также могут использовать (необязательное) локальное имя для использования внутри самого метода (см. Ссылку Jiaaro в комментариях выше).

Это причуда в компиляторе. Функции (которые не являются членами класса) и методы класса имеют разные значения по умолчанию в отношении именованных параметров. Это согласуется с поведением названных параметров в объективе-C (но не имеет смысла для кого-то нового для быстрого, без опыта работы с объективом-C).

Вот что говорит языковая ссылка о именованных параметрах для функций (в частности, параметры, где внешнее имя параметра не задано, а параметр не имеет значения по умолчанию)

Однако эти имена параметров используются только внутри тела самой функции и не могут использоваться при вызове функции. Эти имена параметров называются локальными именами параметров, поскольку они доступны только для использования в теле функции.

Информацию о методах класса см. В ответе Логана.

Обновление 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") 
Interesting Posts
Давайте будем гением компьютера.