What does $0 and $1 mean in Swift Closures?

人走茶凉 提交于 2019-12-18 10:13:21

问题


let sortedNumbers = numbers.sort { $0 > $1 }
print(sortedNumbers)

Can anyone explain, what $0 and $1 means in swift?

More Sample

array.forEach {
    actions.append($0)
}

回答1:


$0 is the first parameter passed into the closure. $1 is the second parameter, etc. That closure you showed is shorthand for:

let sortedNumbers = numbers.sort { (firstObject, secondObject) in 
    return firstObject > secondObject
}



回答2:


It represents shorthanded arguments sent into a closure, this example breaks it down:

Swift 4:

var add = { (arg1: Int, arg2: Int) -> Int in
    return arg1 + arg2
}
add = { (arg1, arg2) -> Int in
    return arg1 + arg2
}
add = { arg1, arg2 in
    arg1 + arg2
}
add = {
    $0 + $1
}

let result = add(20, 20) // 40



回答3:


Swift 5.1

In your example $0 and $1 are Closure’s first and second String's arguments in a Shorthand Argument Names. The shorthand argument names are automatically provided by Swift. The first argument can be referenced by $0, the second argument can be referenced by $1, the third one by $2, and so on.

As you know, a Closure that's very close to a Lambda Function, or a Small Anonymous Function, is a self-contained block of functionality that can be passed around and used in your code. Closure has different names in other programming languages as well as slight differences in meaning – it's Lambda in Python and Kotlin or Block in C and Objective-C.

Let's see how this Closure can be shortened to the form called Shorthand Argument Names:

FIRST EXAMPLE :

let coffee: [String] = ["Cappuccino", "Espresso", "Latte", "Ristretto"]

1. Normal Function

func backward(_ n1: String, _ n2: String) -> Bool {
    return n1 > n2
}
var reverseOrder = coffee.sorted(by: backward)


/* RESULT: ["Ristretto", "Latte", "Espresso", "Cappuccino"] */

2. Inline Closure Expression

reverseOrder = coffee.sorted(by: { (n1: String, n2: String) -> Bool in return n1 > n2 } )

3. Inferring Type From Context

reverseOrder = coffee.sorted(by: { n1, n2 in return n1 > n2 } )

4. Implicit Returns from Single-Expression Closures

reverseOrder = coffee.sorted(by: { n1, n2 in n1 > n2 } )

5. Shorthand Argument Names

reverseOrder = coffee.sorted(by: { $0 > $1 } )

/* $0 and $1 are closure’s first and second String arguments. */

6. Operator Methods

reverseOrder = coffee.sorted(by: >)

/* RESULT: ["Ristretto", "Latte", "Espresso", "Cappuccino"] */

SECOND EXAMPLE :

let companies = ["bmw", "kfc", "ibm", "htc"]

Without a Shorthand Argument Name:

let uppercasedCompanies = companies.map { (item) -> String in item.uppercased() }

/* RESULT: ["BMW", "KFC", "IBM", "HTC"] */

With a Shorthand Argument Name:

let uppercasedCompanies = companies.map { $0.uppercased() }

/* RESULT: ["BMW", "KFC", "IBM", "HTC"] */

THIRD EXAMPLE :

Remainder Operator and Shorthand Argument Name in Higher Order Function filter:

let numbers: [Int] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

let filteredNumbers = numbers.filter { ($0 % 2) == 0 }

print(filteredNumbers)

/* RESULT: [2, 4, 6, 8, 10] */

FOURTH EXAMPLE :

Repeating $0 Shorthand Argument Name for Cubic Degree:

let cubedNumber = { $0 * $0 * $0 } (25)

print(cubedNumber)

/* RESULT:  25^3 = 15625 */

FIFTH EXAMPLE :

Three Shorthand Argument Names – $0, $1, $2:

let math: (Int8, Int8, Int8) -> Int8 = { $0 + $1 - $2 }

func feedClosure() -> (Int8, Int8, Int8) -> Int8 {
    return math
}
feedClosure()(10, 20, 100)

/* RESULT:  (10 + 20 - 100) = -70 */

SIXTH EXAMPLE :

Five Shorthand Argument Names – $0, $1, $2, $3, $4:

let factorial = { $0 * $1 * $2 * $3 * $4 } (1, 2, 3, 4, 5)

print(factorial)

/* RESULT:  5! = 120 */

SEVENTH EXAMPLESwift vs Kotlin vs Python :

Also, let's see how Kotlin's lambda is similar to Swift's closure:

Swift

let element: [String] = ["Argentum","Aurum","Platinum"]

let characterCount = element.map { $0.count }

print(characterCount)

/* RESULT:  [8, 5, 8] */ 

Kotlin

Often Kotlin's lambda expression has only one parameter with implicit name: it.

val element = listOf("Argentum","Aurum","Platinum")

val characterCount = element.map { it.length }

println(characterCount)

/* RESULT:  [8, 5, 8] */ 

But in Python there's no equivalent of Shorthand Argument Name.

Python

element = ["Argentum","Aurum","Platinum"]

characterCount = list(map(lambda x: len(x), element))

print(characterCount)

/* RESULT:  [8, 5, 8] */



回答4:


The refer to the first and second arguments of sort. Here, sort compares 2 elements and order them. You can look up Swift official documentation for more info:

Swift automatically provides shorthand argument names to inline closures, which can be used to refer to the values of the closure’s arguments by the names $0, $1, $2, and so on.




回答5:


In Addition with @Bobby's Answer I would like to Add an Example

var add: (Int,Int,Int)->Int
add = {
//So here the $0 is first argument $1 is second argument $3 is third argument
    return $0 + $1 + $2
//The above statement can also be written as $0 + $1 + $2 i.e is return is optional
}

let result = add(20, 30, 40) 
print(result) // Prints 90



回答6:


It is shorthand argument names.

Swift automatically provides shorthand argument names to inline closures, which can be used to refer to the values of the closure’s arguments by the names $0, $1, $2, and so on.

If you use these shorthand argument names within your closure expression, you can omit the closure’s argument list from its definition, and the number and type of the shorthand argument names will be inferred from the expected function type. The in keyword can also be omitted, because the closure expression is made up entirely of its body:

    reversed = names.sort( { $0 > $1 } )

Here, $0 and $1 refer to the closure’s first and second String arguments.



来源:https://stackoverflow.com/questions/36144322/what-does-0-and-1-mean-in-swift-closures

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!