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

推荐订阅源

F
Full Disclosure
Stack Overflow Blog
Stack Overflow Blog
H
Help Net Security
Microsoft Azure Blog
Microsoft Azure Blog
The GitHub Blog
The GitHub Blog
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Recorded Future
Recorded Future
Y
Y Combinator Blog
Cloudbric
Cloudbric
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
S
Schneier on Security
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
C
Cybersecurity and Infrastructure Security Agency CISA
TaoSecurity Blog
TaoSecurity Blog
Security Latest
Security Latest
N
News and Events Feed by Topic
Hacker News - Newest:
Hacker News - Newest: "LLM"
D
DataBreaches.Net
Security Archives - TechRepublic
Security Archives - TechRepublic
H
Hacker News: Front Page
C
Cisco Blogs
L
LangChain Blog
aimingoo的专栏
aimingoo的专栏
Recent Commits to openclaw:main
Recent Commits to openclaw:main
V
Vulnerabilities – Threatpost
L
LINUX DO - 最新话题
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Google Online Security Blog
Google Online Security Blog
D
Darknet – Hacking Tools, Hacker News & Cyber Security
A
About on SuperTechFans
www.infosecurity-magazine.com
www.infosecurity-magazine.com
Jina AI
Jina AI
C
CXSECURITY Database RSS Feed - CXSecurity.com
Schneier on Security
Schneier on Security
T
Tenable Blog
N
News and Events Feed by Topic
W
WeLiveSecurity
有赞技术团队
有赞技术团队
AI
AI
爱范儿
爱范儿
大猫的无限游戏
大猫的无限游戏
Latest news
Latest news
T
The Blog of Author Tim Ferriss
S
Security Affairs
Know Your Adversary
Know Your Adversary
Simon Willison's Weblog
Simon Willison's Weblog
G
GRAHAM CLULEY
Google DeepMind News
Google DeepMind News
The Cloudflare Blog

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!