Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do I need underscores in swift?

Tags:

swift

People also ask

What does underscore mean in Swift function?

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.

What is _ variable in Swift?

Rules for naming Swift Variables The rules for naming variables are: Variables names must start with either a letter, an underscore _ , or the dollar sign $ . For example, // valid var a = "hello" var _a = "hello" var $a = "hello" Variable names cannot start with numbers.

What does let _ mean in Swift?

In swift, we use the let keyword to declare a constant variable, a constant is a variable that once declared, the value can not be changed.

What is 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.


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. A fuller function declaration looks like this:

func myFunc(label name: Int) // call it like myFunc(label: 3)

"label" is an argument label, and must be present when you call the function. (And since Swift 3, labels are required for all arguments by default.) "name" is the variable name for that argument that you use inside the function. A shorter form looks like this:

func myFunc(name: Int) // call it like myFunc(name: 3)

This is a shortcut that lets you use the same word for both external argument label and internal parameter name. It's equivalent to func myFunc(name name: Int).

If you want your function to be callable without parameter labels, you use the underscore _ to make the label be nothing/ignored. (In that case you have to provide an internal name if you want to be able to use the parameter.)

func myFunc(_ name: Int) // call it like myFunc(3)

In an assignment statement, an underscore means "don't assign to anything". You can use this if you want to call a function that returns a result but don't care about the returned value.

_ = someFunction()

Or, like in the article you linked to, to ignore one element of a returned tuple:

let (x, _) = someFunctionThatReturnsXandY()

When you write a closure that implements some defined function type, you can use the underscore to ignore certain parameters.

PHPhotoLibrary.performChanges( { /* some changes */ },
    completionHandler: { success, _ in // don't care about error
        if success { print("yay") }
    })

Similarly, when declaring a function that adopts a protocol or overrides a superclass method, you can use _ for parameter names to ignore parameters. Since the protocol/superclass might also define that the parameter has no label, you can even end up with two underscores in a row.

class MyView: NSView {
    override func mouseDown(with _: NSEvent) {
        // don't care about event, do same thing for every mouse down
    }
    override func draw(_ _: NSRect) {
        // don't care about dirty rect, always redraw the whole view
    }
}

Somewhat related to the last two styles: when using a flow control construct that binds a local variable/constant, you can use _ to ignore it. For example, if you want to iterate a sequence without needing access to its members:

for _ in 1...20 { // or 0..<20
    // do something 20 times
}

If you're binding tuple cases in a switch statement, the underscore can work as a wildcard, as in this example (shortened from one in The Swift Programming Language):

switch somePoint { // somePoint is an (Int, Int) tuple
case (0, 0):
    print("(0, 0) is at the origin")
case (_, 0):
    print("(\(somePoint.0), 0) is on the x-axis")
case (0, _):
    print("(0, \(somePoint.1)) is on the y-axis")
default:
    print("(\(somePoint.0), \(somePoint.1)) isn't on an axis")
}

One last thing that's not quite related, but which I'll include since (as noted by comments) it seems to lead people here: An underscore in an identifier — e.g. var _foo, func do_the_thing(), struct Stuff_ — means nothing in particular to Swift, but has a few uses among programmers.

Underscores within a name are a style choice, but not preferred in the Swift community, which has strong conventions about using UpperCamelCase for types and lowerCamelCase for all other symbols.

Prefixing or suffixing a symbol name with underscore is a style convention, historically used to distinguish private/internal-use-only symbols from exported API. However, Swift has access modifiers for that, so this convention generally is seen as non-idiomatic in Swift.

A few symbols with double-underscore prefixes (func __foo()) lurk in the depths of Apple's SDKs: These are (Obj)C symbols imported into Swift using the NS_REFINED_FOR_SWIFT attribute. Apple uses that when they want to make a "more Swifty" version of an (Obj)C API — for example, to make a type-agnostic method into a generic method. They need to use the imported API to make the refined Swift version work, so they use the __ to keep it available while hiding it from most tools and documentation.


In addition to the accepted answer, one of the use cases of _ is when you need to write a long number in code

More readable number

🛑 This is not an easy human-readable :

let x = 1000000000000

✅ You can add _ in the number to make it more human-readable:

let x = 1_000_000_000_000

Underscored Interfaces

You may face somewhere in Swift where interfaces begin with a _. Although they are technically declared public but begin with an underscore are NOT considered part of the public interface of this package. We may remove or change them in any release without notice, including minor point releases.

For example @_exportedImport or much more examples here in the official Swift Collections repo

⚠️ Simply don't use them, or you should manually track for changes.


Since Swift 3, specifying parameter names on function calls has become compulsory - even for the first. So, because that could cause huge problem to code written in swift 2, you can use a underscore at the declaration to prevent having to write the parameter name on call. So in this case, it is saying "don't care about the external parameter name". Where the external parameter name is what you call the parameters outside the function (on call) not inside. These external parameter names are called argument labels. http://ericasadun.com/2016/02/09/the-trouble-with-argument-labels-some-thoughts/ ... see how the parameter is given two names? well the first is where the underscore is going.Hope this helps, and do ask if still confused.


func divmod(_ a: Int, _ b:Int) -> (Int, Int) {
    return (a / b, a % b)
}

func divmod(a: Int, b:Int) -> (Int, Int) {
    return (a / b, a % b)
}

The _ is a placeholder for the parameter name. In your example, you call them differently, in the second function, you need to write the parameter name a: 1.

Swift's function name convention is funcName(param1:param2:), and it needs the _ as a placeholder to create the name of the function.

In the first name, the name is

divmod(_:_:)

Whereas the second is

divmod(a:b:)