When are argument labels required in Swift? When are argument labels required in Swift? swift swift

When are argument labels required in Swift?


All init methods require parameter names:

var view = NSView(frame: NSRect(x: 10, y: 10, width: 50, height: 50))class Foo {    init(one: Int, two: String) { }}let foo = Foo(one: 42, two: "Hello world")

All methods called on an object use parameter names for everything but the first parameter:

extension Foo {    func run(one: String, two: [Int]) { }}foo.run("Goodbye", two: [])

All including class functions in Swift and objective-c follow the same pattern. You also can explicitly add external names.

extension Foo{class func baz(one: Int, two: String){}class func other(exOne one: Int,  exTwo two: String){}}Foo.baz(10, two:"str")Foo.other(exOne: 20, exTwo:"str")

Swift functions that are not a class function don't require parameter names, but you still can explicitly add them:

func bar(one: Int, two: String){}bar(1, "hello")

As Bryan said, it's to make Swift method calls make sense when called on objective-c methods that have parameter names in the method signature. Init methods include the first parameter because Swift changes the init methods from objective-c from initWith:... to Class() so the first parameter name is no longer included in the method name.


As of Swift 3.0 this has changed again: all methods, functions, and initializers require argument labels for all parameters, unless you have explicitly opted out using the external name _. This means methods such as addChildViewController(_:) are now written like this:

func addChildViewController(_ childController: UIViewController)

This was proposed and approved as part of the Swift Evolution process, and was implemented in SR-961.


Swift 3.0

In Swift 3.0, slated to be released in late 2016, the default behavior is simple:

  • All parameters to all methods have external labels by default.

You can find these rules most concisely in the Swift API Design Guidelines. This newest behavior was proposed in SE-0056, "establish consistent label behavior across all parameters including first labels," and implemented in SR-961. The default behavior may be changed as described below, in "Overriding the Default Behavior."

Swift 2.2

In Swift 2.2, the language's defaults for the presence of external argument labels have changed and are now simpler. The default behavior can be summarized as follows:

  • First parameters to methods and functions should not have external argument labels.
  • Other parameters to methods and functions should have external argument labels.
  • All parameters to initializers should have external argument labels.

The default behavior may be changed as described below, in "Overriding the Default Behavior."

An Example

These rules are best demonstrated with an example:

func printAnimal(animal: String, legCount: Int) {    let legNoun = legCount == 1 ? "leg" : "legs"    print("\(animal) has \(legCount) \(legNoun)")}struct Player {    let name: String    let lives: Int    init(name: String, lives: Int) {        self.name = name        self.lives = lives    }    func printCurrentScore(currentScore: Int, highScore: Int) {        print("\(name)'s score is \(currentScore). Their high score is \(highScore)")    }}// SWIFT 3.0// In Swift 3.0, all argument labels must be includedprintAnimal(animal: "Dog", legCount: 4)let p = Player(name: "Riley", lives: 3)p.printCurrentScore(currentScore: 50, highScore: 110)// SWIFT 2.2// In Swift 2.2, argument labels must be included or omitted in exactly the following way// given the definition of the various objects.printAnimal("Dog", legCount: 4)let p = Player(name: "Riley", lives: 3)p.printCurrentScore(50, highScore: 110)// In Swift 2.2, none of the following will workprintAnimal(animal: "Dog", legCount: 4)  // Extraneous argument label 'animal:' in calllet q = Player("Riley", lives: 3)  // Missing argument label 'name:' in callp.printCurrentScore(50, 110)  // Missing argument label 'highScore:' in call

Overriding the Default Behavior

For any parameter to any method or function, you may deviate from the language's default, though the style guide rightly warns you not to do so unless there's a good reason.

To add an external parameter label where there would normally not be one – only applicable in Swift 2.2, since Swift 3.0 defaults to assigning external labels to every parameter – or to change an external parameter label – applicable to both versions – write the desired external parameter label before the local parameter label:

func printAnimal(theAnimal animal: String, legCount: Int) {    let legNoun = legCount == 1 ? "leg" : "legs"    print("\(animal) has \(legCount) \(legNoun)")}printAnimal(theAnimal: "Dog", legCount: 4)

To remove an external parameter label where there normally would be one, use the special external parameter label _:

func printAnimal(animal: String, _ legCount: Int) {    let legNoun = legCount == 1 ? "leg" : "legs"    print("\(animal) has \(legCount) \(legNoun)")}// SWIFT 3.0printAnimal(theAnimal: "Dog", 4)// SWIFT 2.2printAnimal("Dog", 4)

These "default overrides" will work for any method or function, including initializers.