Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift error: missing argument label 'name:' in call

Tags:

swift

I'm learning about default arguments and I ran aground of something weird:

import UIKit

func greet(name: String = "world") {
    println("hello \(name)")
}

greet("jiaaro")

this throws an error:

Playground execution failed: error: <REPL>:9:7: error: missing argument label 'name:' in call
greet("jiaaro")
      ^
      name:

I understand that it wants greet(name: "jiaaro") but I don't understand why that should be necessary.

like image 455
Jiaaro Avatar asked Jun 04 '14 23:06

Jiaaro


3 Answers

Swift functions can specify local and external argument names:

func greet(who name: String = "world") {
    println("hello \(name)")
}

// prints "hello world"
greet()

// prints "hello jiaaro"
greet(who:"jiaaro")

// error
greet("jiaaro")

// error
greet(name: "jiaaro")

To opt out of this behavior you can use an underscore for the external name. Note that the first parameter implicitly uses the "no external name" behavior:

func greet(name: String = "world", _ hello: String = "hello") {
    println("\(hello) \(name)")
}

// prints "hello world"
greet()

// prints "hello jiaaro"
greet("jiaaro")

// prints "hi jiaaro"
greet("jiaaro", "hi")

// error
greet(name: "jiaaro")

The following is now disallowed in Swift 2.0, see below for equivalent code.

You can use the # prefix to use the same local and external name for the first parameter:

func greet(#name: String = "world", hello: String = "hello") {
    println("\(hello) \(name)")
}

// prints "hi jiaaro"
greet(name: "jiaaro", hello: "hi")

Swift 2.0 code:

func greet(name name: String = "world", hello: String = "hello") {
    println("\(hello) \(name)")
}

// prints "hi jiaaro"
greet(name: "jiaaro", hello: "hi")
like image 168
Jiaaro Avatar answered Nov 15 '22 21:11

Jiaaro


Swift requires argument labels by default, because it supports classes with multiple initializers. The benefit of argument labels comes from the ability of Swift to infer which initializer to use; not only by argument type, but argument name as well.

struct Celsius {
    var temperatureInCelsius: Double = 0.0

    init(fromFahrenheit fahrenheit: Double) {
        temperatureInCelsius = (fahrenheit - 32.0) / 1.8
    }

    init(fromKelvin kelvin: Double) {
        temperatureInCelsius = kelvin - 273.15
    }
}

let boilingPointOfWater = Celsius(fromFahrenheit: 212.0)
// boilingPointOfWater.temperatureInCelsius is 100.0

let freezingPointOfWater = Celsius(fromKelvin: 273.15)
// freezingPointOfWater.temperatureInCelsius is 0.0

See this page for more details: https://developer.apple.com/library/prerelease/ios/documentation/swift/conceptual/Swift_Programming_Language/Initialization.html#//apple_ref/doc/uid/TP40014097-CH18-XID_272

like image 3
HZN Avatar answered Nov 15 '22 19:11

HZN


I just wanted to add that now your code

func greet(name: String = "world") {
    print("hello \(name)")
}

greet("jiaaro")

works fine in xcode, i just changed "println" with "print"

like image 1
TmSmth Avatar answered Nov 15 '22 21:11

TmSmth