What does _: mean in Swift?
Categories:
Understanding the Underscore Colon (_:
) in Swift
Explore the various meanings and uses of the underscore colon (_:
) syntax in Swift, from external parameter names to type annotations and pattern matching.
The _:
syntax in Swift can appear in several contexts, each with a distinct meaning. While it might seem cryptic at first, understanding its different applications is crucial for writing clear, concise, and idiomatic Swift code. This article will break down the primary uses of _:
to help you master this versatile Swift construct.
1. Omitting External Parameter Names in Functions
One of the most common uses of _:
is to explicitly omit an external parameter name for a function argument. By default, Swift functions require external parameter names for all parameters after the first one, making calls more readable. However, there are situations where you might want to call a function without specifying an external name for a particular argument. This is where _
comes in handy.
func greet(person name: String, from city: String) {
print("Hello \(name) from \(city)!")
}
greet(person: "Alice", from: "New York") // External names 'person' and 'from' are used
func greetWithoutExternalName(_ name: String, from city: String) {
print("Hello \(name) from \(city)!")
}
greetWithoutExternalName("Bob", from: "London") // 'name' parameter has no external name
Demonstrating the omission of an external parameter name using _
.
_
to omit external parameter names can make function calls more concise, especially for common utility functions or when the parameter's role is clear from its type or context.2. Type Annotation in Closures and Tuples
The _:
syntax can also appear in type annotations, particularly within closures or when dealing with tuples, to indicate that a specific element's value is not used or that its type is inferred. This is less about omitting a name and more about signaling intent or allowing type inference to handle the details.
// In a closure, _ can represent an unused parameter
let numbers = [1, 2, 3]
let doubledNumbers = numbers.map { _ in
return 2 * 5 // The element itself is not used, only its presence matters
}
print(doubledNumbers) // Output: [10, 10, 10]
// In a tuple, _ can ignore a specific element's value
let http404Error = (404, "Not Found")
let (statusCode, _) = http404Error
print("The status code is \(statusCode)") // Output: The status code is 404
Using _
for unused closure parameters and tuple element ignoring.
3. Pattern Matching with Wildcard Pattern
In switch
statements and for-in
loops, _
acts as a wildcard pattern. It matches any value of a given type without binding that value to a variable. This is incredibly useful when you only care about certain parts of a value or when you want to execute code for any remaining cases without needing to reference the matched value.
let somePoint = (1, 1)
switch somePoint {
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")
case (-2...2, -2...2):
print("(\(somePoint.0), \(somePoint.1)) is inside the box")
default:
print("(\(somePoint.0), \(somePoint.1)) is outside the box")
}
Using _
as a wildcard pattern in a switch
statement.
flowchart TD A[Function Definition] --> B{Parameter Name Needed?} B -- Yes --> C[Provide External Name] B -- No (e.g., first param, or explicit omission) --> D[Use `_`] D --> E[Function Call] E --> F{Parameter Value Used?} F -- No (e.g., closure, tuple ignore) --> G[Use `_`] F -- Yes --> H[Bind to Variable] G --> I[Pattern Matching] I --> J{Value Needed?} J -- No (e.g., `switch` default) --> K[Use `_`] J -- Yes --> L[Bind to Variable]
Decision flow for when to use _
in Swift.
4. Discarding Values in for-in
Loops
Similar to pattern matching in switch
statements, _
can be used in for-in
loops when you iterate over a sequence but only care about the side effects of the iteration or a specific part of the iterated item, not the item itself.
// Iterating over a range, but only performing an action a certain number of times
for _ in 1...5 {
print("Hello!")
}
// Iterating over a dictionary, only interested in keys
let ages = ["Alice": 30, "Bob": 25]
for (name, _) in ages {
print("Person: \(name)")
}
Using _
to discard values in for-in
loops.
_
is powerful for conciseness, use it judiciously. Overuse can make code harder to read if the intent isn't immediately clear. Always prioritize readability and maintainability.