惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
雷峰网
雷峰网
Recent Announcements
Recent Announcements
月光博客
月光博客
G
Google Developers Blog
腾讯CDC
S
Secure Thoughts
大猫的无限游戏
大猫的无限游戏
T
Tenable Blog
云风的 BLOG
云风的 BLOG
W
WeLiveSecurity
博客园 - 【当耐特】
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
博客园 - 聂微东
The Cloudflare Blog
阮一峰的网络日志
阮一峰的网络日志
人人都是产品经理
人人都是产品经理
P
Privacy International News Feed
MyScale Blog
MyScale Blog
K
Kaspersky official blog
T
The Blog of Author Tim Ferriss
Attack and Defense Labs
Attack and Defense Labs
Spread Privacy
Spread Privacy
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
aimingoo的专栏
aimingoo的专栏
I
Intezer
Vercel News
Vercel News
小众软件
小众软件
Simon Willison's Weblog
Simon Willison's Weblog
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
N
Netflix TechBlog - Medium
P
Proofpoint News Feed
Latest news
Latest news
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
T
Tor Project blog
S
Security Affairs
P
Proofpoint News Feed
博客园 - 三生石上(FineUI控件)
博客园 - Franky
C
Cyber Attacks, Cyber Crime and Cyber Security
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
美团技术团队
Recent Commits to openclaw:main
Recent Commits to openclaw:main
S
Security @ Cisco Blogs
L
LINUX DO - 热门话题
Know Your Adversary
Know Your Adversary
Project Zero
Project Zero
D
Docker
L
Lohrmann on Cybersecurity
F
Full Disclosure

Dmitri Pavlutin Blog

Pure Functions in JavaScript: A Beginner's Guide Record Type in TypeScript: A Quick Intro How to Write Comments in React: The Good, the Bad and the Ugly 4 Ways to Create an Enum in JavaScript React forwardRef(): How to Pass Refs to Child Components TypeScript Function Types: A Beginner's Guide How to Use v-model to Access Input Values in Vue Mastering Vue refs: From Zero to Hero Environment Variables in JavaScript: process.env 5 Must-Know Differences Between ref() and reactive() in Vue How to Destructure Props in Vue (Composition API) Triangulation in Test-Driven Development How to Use nextTick() in Vue Programming to Interface Vs to Implementation A Smarter JavaScript Mapper: array.flatMap() Array Grouping in JavaScript: Object.groupBy() How to Access ES Module Metadata using import.meta JSON Modules in JavaScript How to Trim Strings in JavaScript TypeScript Function Overloading How to Debounce and Throttle Callbacks in Vue How to Show/Hide Elements in Vue Sparse vs Dense Arrays in JavaScript How to Fill an Array with Initial Values in JavaScript Covariance and Contravariance in TypeScript What are Higher-Order Functions in JavaScript? How to Use TypeScript with React Components Index Signatures in TypeScript How to Use React useReducer() Hook unknown vs any in TypeScript A Guide to React Context and useContext() Hook How to Use Promise.any() 2 Ways to Remove a Property from an Object in JavaScript 'return await promise' vs 'return promise' in JavaScript How to Use Promise.allSettled() How to Use fetch() with JSON JavaScript Promises: then(f,f) vs then(f).catch(f) What is a Promise in JavaScript? How to Use Promise.all() A Simple Guide to Component Props in React Don't Stop Me Now: How to Use React useTransition() hook A Simple Explanation of JavaScript Variables: const, let, var ES Modules Dynamic Import How to Memoize with React.useMemo() How to Cleanup Async Effects in React Why Math.max() Without Arguments Returns -Infinity How to Debounce and Throttle Callbacks in React Don't Confuse Function Expressions and Function Declarations in JavaScript How to Use ES Modules in Node.js Solving a Mystery Behavior of parseInt() in JavaScript How to Use Array Reduce Method in JavaScript 3 Ways to Merge Arrays in JavaScript A Guide to Jotai: the Minimalist React State Management Library The Difference Between Values and References in JavaScript How to Implement a Queue in JavaScript A Helpful Algorithm to Determine "this" value in JavaScript React useRef() Hook Explained in 3 Steps 7 Interview Questions on "this" keyword in JavaScript. Can You Answer Them? How to Greatly Enhance fetch() with the Decorator Pattern 7 Interview Questions on JavaScript Closures. Can You Answer Them? What's a Method in JavaScript? array.sort() Does Not Simply Sort Numbers in JavaScript How to Solve the Infinite Loop of React.useEffect() The New Array Method You'll Enjoy: array.at(index) What's the Difference between DOM Node and Element? Why Promises Are Faster Than setTimeout()? Everything About Callback Functions in JavaScript How React Updates State 5 Mistakes to Avoid When Using React Hooks 5 Best Practices to Write Quality JavaScript Variables Type checking in JavaScript: typeof and instanceof operators 3 Ways to Check if a Variable is Defined in JavaScript React Forms Tutorial: Access Input Values, Validate, Submit Forms Prototypal Inheritance in JavaScript How to Timeout a fetch() Request How to Learn JavaScript If You're a Beginner A Simple Explanation of React.useEffect() A Simple Explanation of JavaScript Iterators How to Use React Controlled Inputs Everything about null in JavaScript How to Use Fetch with async/await Getting Started with Arrow Functions in JavaScript An Interesting Explanation of async/await in JavaScript Front-end Architecture: Stable and Volatile Dependencies Is it Safe to Compare JavaScript Strings? How to Access Object's Keys, Values, and Entries in JavaScript What Actually is a String in JavaScript? 3 Ways to Shallow Clone Objects in JavaScript (w/ bonuses) Checking if an Array Contains a Value in JavaScript JavaScript Event Delegation: A Beginner's Guide How to Parse URL in JavaScript: hostname, pathname, query, hash 3 Ways to Detect an Array in JavaScript How to Get the Screen, Window, and Web Page Sizes in JavaScript 3 Ways to Check If an Object Has a Property/Key in JavaScript How to Compare Objects in JavaScript Object.is() vs Strict Equality Operator in JavaScript Own and Inherited Properties in JavaScript 5 Differences Between Arrow and Regular Functions How to Use Object Destructuring in JavaScript Your Guide to React.useCallback()
Useful Details About Underscore Keyword in Swift
Dmitri Pavlutin · 2016-10-25 · via Dmitri Pavlutin Blog

Swift is known for its ability to help creating readable and self explanatory code. Such practice is efficient, because writing meaningful code has a big impact on understanding: and as result on productivity.

The language offers useful syntax to improve the readability using argument labels, or to access a tuple or structure component.

For instance the following function returns a tuple that contains the minimum and maximum values from the provided two arguments:


func getMinMax(a: Int, b: Int) -> (Int, Int) {

if (a < b) {

return (min: a, max: b)

}

return (min: b, max: a)

}

let (min, max) = getMinMax(a: 15, b: 8)

print(min) // => 8

print(max) // => 15


The invocation getMinMax(a: 15, b: 8) has a and b as argument labels. These indicate additional information about the arguments.

Every medal has two sides. There are situations where verbose code becomes redundant. It talks too much than it's necessary.

Every medal has two sides

Thinking better about the previous example, it is possible that a and b argument labels do not provide useful information. And suppose you want to access only the minimum from the returned tuple let (min, max) = getMinMax().

For such cases Swift provides the wildcard pattern - a special underscore character _.

Let's use the underscore and transform the previous example:


func getMinMax(_ a: Int, _ b: Int) -> (Int, Int) {

if (a < b) {

return (min: a, max: b)

}

return (min: b, max: a)

}

let (min, _) = getMinMax(15, 8)

print(min) // => 8


The function signature is changed to getMinMax(_ a: Int, _ b: Int), where _ is inserted before the parameter name. This means that argument labels are not necessary on invocation: getMinMax(15, 8).
Also the max component of the tuple can be skipped on extraction: let (min, _).

Let's study the situations where underscore _ helps avoiding redundant details.

1. Omitting argument labels

Starting version 3.0 Swift requires by default to indicate the argument labels on invocation.
The parameter name paramName in func myFunc(paramName: Type) {...} automatically create argument label paramName: on invocation myFunc(paramName: valueOfType).

Let's see a simple case:


func sum(x: Int, y: Int) -> Int {

return x + y

}

print(sum(x: 10, y: 5)) // => 15


When invoking sum function, you have to indicate the argument labels x: and y: for both arguments: sum(x: 10, y: 5).

As mentioned in the introduction, if you want to omit the argument label, insert an underscore before the parameter name: func sum(_ x: Int, ...) {...}.

Let's modify the previous example:


func sum(_ x: Int, _ y: Int) -> Int {

return x + y

}

print(sum(10, 5)) // => 15


Since the argument label is not necessary, the invocation sum(10, 5) looks better. It's clear that 10 and 5 are the operands in a sum operation. No more details are necessary.

You can use _ to suppress the argument label every time its indication seems redundant.

2. Ignore tuple component

Tuples are simple data structures that are used to couple related values. They are especially useful when returning multiple values from a function.

Let's create a complex function that executes 4 arithmetic operations:

  • Addition
  • Subtraction
  • Multiplication
  • Division

Since all the operations are related, they are returned in a tuple:


func calculateOperations(_ first: Int, _ second: Int)

-> (add: Int, sub: Int, mul: Int, div: Int) {

return (

add: first + second,

sub: first - second,

mul: first * second,

div: first / second

)

}

let (add, sub, mul, div) = calculateOperations(8, 6)

print(add, sub, mul, div) // => 14 2 48 1


let (add, sub, mul, div) extracts the tuple components into variables.

Suppose you need to access only the subtraction and division results: the underscore fits nice it this situation. Replace the unnecessary variables add and mul with an underscore _:


// ...

let (_, sub, _, div) = calculateOperations(8, 6)

print(sub, div) // => 2 1


let (_, sub, _, div) contains _ at first and third positions. This indicates that addition and multiplication results are insignificant.

Alternatively you can retrieve the tuple instance into a variable, and use a selector to access the named tuples components:


// ...

let result = calculateOperations(8, 6)

print(result.sub, result.div) // => 2 1

print(result.1, result.3) // => 2 1


result.sub and result.div (or result.1 and result.3) selects tuple's named components sub and div.
The downside of this approach is the need to keep a variable for tuple. And later access the components using a selector.

3. Ignore enumeration associated value

Swift is so kind that besides simple enumeration, you can associate for each enumeration case a value. These are similar to tagged unions data structure from computer science.

Enumeration is a powerful data structure, especially in combination with associated values. However extracting data from such complex structure has some overhead, especially to access the associated values.

For instance let's enumerate the flight phases of an aircraft. An aircraft can:

  • Stay on the ground without movement (fixed)
  • It can accelerate with a specific speed before take-off (acceleration (Int))
  • It can fly with a specific speed and altitude (flight(Int, Int))
  • And land with a specific speed (landing(Int))

Let's code the enumeration:


enum FlightPhase {

case fixed

case acceleration(Int)

case flight(Int, Int)

case landing(Int)

}


One of the most important characteristic of a flying aircraft is the speed. Let's add to enumeration a new method getSpeed():


enum FlightPhase {

case fixed

case acceleration(Int)

case flight(Int, Int)

case landing(Int)

func getSpeed() -> Int {

switch self {

case .fixed:

return 0

case .acceleration(let speed):

return speed

case .flight(let speed, _):

return speed

case .landing(let speed):

return speed

}

}

}

let flying: FlightPhase = .flight(700, 3000)

print(flying.getSpeed()) // => 700


The flight speed case .flight(let speed, _) omits the information about the altitude using an underscore _. Extracting the altitude in this case is simply not necessary.

Even if the altitude info is extracted .flight(let speed, let altitude), but later not used, Swift triggers a warning: immutable value 'altitude' was never used. The underscore helps solving such situations.

4. Skip function invocation result

Swift 3.0 implements an interesting mechanism that warns developer when a function invocation result (non Void) is not used.

For example the following code triggers a warning:


func greet(_ name: String = "World") -> String {

return "Hello, \(name)!"

}

greet("Alexandra")

// => Triggers "warning: result of call to 'greet' is unused"


Because the invocation result of greet("Alexandra") is not used, the Swift compiler warns about the unused value.

Of course the correct solution is either to mark that the function returns nothing (-> Void) or simply use the returned value.

Otherwise you can discard the result using an underscore:


// ...

_ = greet("Alexandra")


Such way you let know the compiler that you ignore the returned value. And no warning is triggered in this case.

5. Skip closure parameters

If you need to skip naming some closure parameters, just mark those with underscores. For example the first and second parameters in { _, _, param3, param4 in ... } are skipped.

Let's filter an array and keep the elements on even positions:


let colors = ["green", "blue", "white", "yellow", "orange"]

let evenColors = colors.enumerated().filter { index, _ in

return index % 2 == 0

}.map { value in value.1 }

print(evenColors) // => ["green", "white", "orange"]


.filter() method accepts a closure that receives index and value values on each iteration. Because the intent is to check whether the index is even, the value parameter is skipped using an underscore _: .filter { index, _ in ...}.

6. Skip iteration value

Another common usage of the underscore is to iterate a code block a particular number of times, and ignore the iteration value.

For example, let's run 5 iterations using a for-in cycle:


let base = 2

let exponent = 5

var power = 1

for _ in 1...exponent {

power *= base

}

print(power) // => 32


Since the sequence value on each iteration is insignificant, _ is used instead of a variable in the loop for _ in 1...exponent.

7. Final words

Swift suggests developer to practice writing meaningful and detailed code. While it works in most of the cases, sometimes providing additional details is redundant.

The small underscore character _ can be used in such situations, to skip the unnecessary details.

In the function signature func myFunc(_ paramName: Type) {...} use _ to skip providing the argument label on invocation myFunc(valueOfType).

You can omit unnecessary extractions from tuple components let (value, _) = ... or enumeration associated values case .enumCase(value, _).

On a function invocation _ = myFunc() you can also suppress the usage of the returned value. However this workaround should be applied as an exception, since in most of the cases the result should be used.

Do you know other useful applications of the underscore in Swift? Feel free to write a comment below!