Does "Let _ = ..." (Let Underscore Equal) Have Any Use in Swift

Does let _ = ... (let underscore equal) have any use in Swift?

You will get a compiler warning if the method has been marked with a warn_unused_result from the developer documentation:

Apply this attribute to a method or function declaration to have the compiler emit a warning when the method or function is called without using its result.

You can use this attribute to provide a warning message about incorrect usage of a nonmutating method that has a mutating counterpart.

Underscore in Swift functions

So, you would just use the underscore if you don't want the user to have to input the name of the variable. For instance func foo(x: Int, y: Int) is called foo(6, y: 10) so if you didn't want whoever is calling the function to have to write the y you would create the function as func foo(x: Int, _ y: Int). Furthermore, if you wanted the called to have to write x and y, you would write func foo(x x: Int, y: Int). All of this is stylistic. Therefore, I would just do what makes sense. In xCode, there is obviously autocomplete so I always just leave the parameter names in because that makes the code clearer. So, there is no real point to having the underscore or function variable names other than making your code easier to understand.

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

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.

Assigning a Variable to an Underscore in Swift

This test shows that the object is created and then destroyed when the object goes out of scope:

class ToDoItem {
var title = ""

init(title: String) {
self.title = title
}

deinit {
print("deinit \(title)")
}
}

func test() {
print("test")

_ = ToDoItem(title: "First")
_ = ToDoItem(title: "Second")

print("end test")
}

func callTest() {
print("calling test()...")
test()
print("back from test()")
}

callTest()

Output:

calling test()...
test
end test
deinit Second
deinit First
back from test()

Extended test:

func test() {
print("test")

_ = ToDoItem(title: "Item 1")
for i in 2...4 {
_ = ToDoItem(title: "Item \(i)")
}
_ = ToDoItem(title: "Item 5")

print("end test")
}
calling test()...
test
deinit Item 2
deinit Item 3
deinit Item 4
end test
deinit Item 5
deinit Item 1
back from test()

Notice that items 2, 3 and 4 are deinitialized as they go out of scope in each loop. Items 1 and 5 are deinitialized when they go out of scope when test() completes.


Inside of an App

As Dmitry Plotnikov noted in his answer, the above is true only in a Swift Playground. In an app, the results are:

calling test()...
test
deinit Item 1
deinit Item 2
deinit Item 3
deinit Item 4
deinit Item 5
end test
back from test()

That tells us:

  1. The objects are created.
  2. They are freed immediately.

Why do I need underscores 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. 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.

Variable declaration with underscore

The first examples are essentially creating properties that are publicly readable but privately writable.

The second set of code does not do the same thing as the first set.

The proper way to write this code is:

private (set) var name: String // no need for the !
private (set) var studentID: Int // no need for the !

init(name: String, studentID: Int) {
self.name = name
self.studentID = studentID
}

This makes the properties readable by outside users but only settable by the class. This is what the 1st set of code implements but in a much more verbose and needless manner.

The use of underscore is just a naming convention carried over from Objective-C when creating private instance variables.

Personally, I'd avoid videos and tutorials that use the 1st set of code.

Does the underscore symbol ignore or check for nullity in a switch statement in Swift?

The underscore matches any value (nil or non-nil), but that is also
the case for your pattern:

case (let someObject, let current, nil):

where the first let someObject matches any value (nil or non-nil). So this does actually not work as you intended.

The optional type is defined as an enumeration:

enum Optional<T> : ... {
case None
case Some(T)
// ....
}

and nil is the same as Optional.None.
Therefore you can use

case (.Some, _, nil):
// Alternatively:
case (.Some, _, .None):

to match the case where the first element is not nil and the last
element is nil. The middle element of (SomeObject?, SomeObject, SomeObject?) is not an optional so it cannot be nil.

As of Swift 2 / Xcode 7, the x? pattern can be used as a synonym
for .Some(x), in your case

case (_?, _, nil):

matches the case where the first element is not nil and the last element is nil.

How to replace spaces in string with underscore

Proper implementation is the exact same as Swift 3:

let str = "New York"
let replaced = str.replacingOccurrences(of: " ", with: "_")

Swifty-JSON: unable to parse underscore

This issue has been fixed by replacing Tab to Whitespace.



Related Topics



Leave a reply



Submit