Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the _ underscore representative of in Swift References?

People also ask

What does _ in Swift function mean?

In Swift, the underscore operator (_) represents an unnamed parameter/label. In for loops, using the underscore looping parameter is practical if you do not need the looping parameter in the loop.

What does underscore mean in Swift?

There are a few nuances to different use cases, but generally an underscore means "ignore this". When declaring a new function, an underscore tells Swift that the parameter should have no label when called — that's the case you're seeing.


Both answers were correct but I want to clarify a little bit more.

_ is used to modify external parameter name behavior for methods.

In Local and External Parameter Names for Methods section of the documentation, it says:

Swift gives the first parameter name in a method a local parameter name by default, and gives the second and subsequent parameter names both local and external parameter names by default.

On the other hand, functions by default don't have external parameter names.

For example, we have this foo() method defined in class Bar:

class Bar{
    func foo(s1: String, s2: String) -> String {
        return s1 + s2;
    }
}

When you call foo(), it is called like bar.foo("Hello", s2: "World").

But, you can override this behavior by using _ in front of s2 where it's declared.

func foo(s1: String, _ s2: String) -> String{
    return s1 + s2;
}

Then, when you call foo, it could be simply called like bar.foo("Hello", "World") without the name of the second parameter.

Back to your case, runAction is a method because it's associated with type SKNode, obviously. Thus, putting a _ before parameter action allows you to call runAction without an external name.

Update for Swift 2.0

Function and method now work the same way in terms of local and external argument name declaration.

Functions are now called by using external parameter name by default, starting at 2nd parameter. This rule only applies to pure Swift code.

So, by providing an _ in front of a function, the caller won't have to specify external parameter name, just like what you would do for a method.


The underscore is a general token used to indicate a discarded value.

In this specific case, it means that the function will be invoked as runAction(argument) instead of runAction(action:argument)

In other contexts it has other similar meaning, e.g. in:

for _ in 0..<5 { ... }

It means that we merely want to execute the block 5 times and we don't care about the index within the block.

In this context:

let (result, _) = someFunctionThatReturnsATuple()

It means that we don't care what the second element of the tuple is, only the first.


Since Swift 3 all argument labels are required by default.

You can force an IDE to hide an argument label with _.

func foo(a: String) {
}

func foo2(_ a: String) {
}

called foo(a: "abc") and foo2("abc")

Note: This can be used only when a is the (external) argument label and (internal) variable name at the same time. It's equivalent - func foo(a a: String) won't accept the _.

Why is Apple using it?

You can see Apple is using it across the API. Apple's libraries are still written in Objective-C (if not, they share the same function names anyway, which were designed for Objective-C syntax)

Functions like applicationWillResignActive(_ application: UIApplication) would have redundant parameter name application, since there is already the application in it's function name.

Your example

func runAction(_ action: SKAction!) would be called without it's _ mark like runAction(action:). The parameter name action would be redundant since there is already one in the function name. That's the purpose and why it's there.


An identifier in front of parameter declaration defines an external parameter name. This is the name that must be provided by the caller when calling the function:

func someFunction(externalParameterName localParameterName: Int)

Swift provides an automatic external name for any defaulted parameter you define, if you do not provide an external name yourself. Using an underscore for the external parameter name opts out from this behavior:

You can opt out of this behavior by writing an underscore (_) instead of an explicit external name when you define the parameter.

You can read more about this behavior in the section on External Names for Parameters with Default Values here.


I think this forces a convention in Swift that makes it read closer to objective-c, which matches cocoa conventions better. In objc you don't (externally) name your first parameter. Instead, by convention you usually include the external name in the latter part of the method name like this:

- (void)myFancyMethodWithFirstName:(NSString *)aFirstName lastName:(NSString *)aLastName;

[someInstance myFancyMethodWithFirstName:@"John" lastName:@"Doe"];

To make Swift api calls consistent with objc you will want to suppress the external parameter name of the first param.

func myFancyMethodWithFirstName(_ firstName:String, lastName:String);

someInstance.myFancyMethodWithFirstName("John", lastName:"Doe")

Actually, there is a difference between the real code used to define a method and the method declaration in Apple's docs. Let's take UIControl's - addTarget:action:forControlEvents: method for example, the real code is: enter image description here

But in docs, it appear like this (notice _ before target): enter image description here

In real code, _ is used to make the second or subsequent parameter's external name not appear when a method is called, while in docs, _ before a parameter's local name indicates that when you call a method or a function, you should not provide an external name.

There's no external name when a function is called by default unless you provide your own or add # before (without whitespace) a parameter's local name, for example, this is how we use dispatch_after: enter image description here

And in docs, it appear like this (notice three _): enter image description here

The convention of function's declaration is just the same as I have described for method.