Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When are argument labels required in Swift?

Tags:

syntax

swift

In answering this question it came about that argument labels were required for a call to init. This is normal in Swift.

class Foo {     init(one: Int, two: String) { } }  let foo = Foo(42, "Hello world") // Missing argument labels 'one:two:' in call 

However, stranger forces are at play:

extension Foo {     func run(one: String, two: [Int]) { } }  foo.run(one: "Goodbye", two: []) // Extraneous argument label 'one:' in call 

To use an argument label here it would have to be declared explicitly.

I haven't seen something very thorough explaining all of this in the documentation. For which varieties of class/instance/global functions are argument labels required? Are Obj-C methods always exported and imported with argument labels?

like image 423
jtbandes Avatar asked Jul 18 '14 00:07

jtbandes


People also ask

What is an argument label in Swift?

The argument label is used when calling the function; each argument is written in the function call with its argument label before it. The parameter name is used in the implementation of the function. By default, parameters use their parameter name as their argument label.

How do you omit an argument label in Swift?

To omit argument labels, use a _ before the parameter name. A parameter name is still necessary to access the argument's value inside the function. Omitting the argument label might be wanted to make the function more readable.

What is Inout in Swift?

Swift inout parameter is a parameter that can be changed inside the function where it's passed into. To accept inout parameters, use the inout keyword in front of an argument. To pass a variable as an inout parameter, use the & operator in front of the parameter.


2 Answers

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.

like image 93
Connor Avatar answered Oct 22 '22 08:10

Connor


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.

like image 36
TwoStraws Avatar answered Oct 22 '22 06:10

TwoStraws