let sortedNumbers = numbers.sort { $0 > $1 }
print(sortedNumbers)
Kann jemand erklären, was $0
und $1
was schnell bedeutet?
Mehr Probe
array.forEach {
actions.append($0)
}
$0
ist der erste Parameter, der an den Abschluss übergeben wird. $1
ist der zweite Parameter usw. Der von Ihnen gezeigte Abschluss ist eine Abkürzung für:
let sortedNumbers = numbers.sort { (firstObject, secondObject) in
return firstObject > secondObject
}
TL; DR
Swift 5.3
Wie Sie wissen, ist ein Closure ein in sich geschlossener Funktionsblock (eine Funktion ohne Namen), der weitergegeben und in Ihrem Code verwendet werden kann. Closure hat andere Namen in anderen Programmiersprachen sowie geringfügige Bedeutungsunterschiede - es ist Lambda in Python und Kotlin oder Block in C und Objective-C .
Schließen eines Verschlusses
let coffee: [String] = ["Cappuccino", "Espresso", "Latte", "Ristretto"]
1. Normale Funktion
func backward(_ n1: String, _ n2: String) -> Bool { return n1 > n2 } var reverseOrder = coffee.sorted(by: backward) /* RESULT: ["Ristretto", "Latte", "Espresso", "Cappuccino"] */
2. Inline-Abschlussausdruck
reverseOrder = coffee.sorted(by: { (n1: String, n2: String) -> Bool in return n1 > n2 } )
3. Typ aus dem Kontext ableiten
reverseOrder = coffee.sorted(by: { n1, n2 in return n1 > n2 } )
4. Implizite Rückgaben von Einzelausdrucksabschlüssen
reverseOrder = coffee.sorted(by: { n1, n2 in n1 > n2 } )
5. Kurzargumentnamen
reverseOrder = coffee.sorted(by: { $0 > $1 } ) /* $0 and $1 are closure’s first and second String arguments. */
6. Operatormethoden
reverseOrder = coffee.sorted(by: >) /* RESULT: ["Ristretto", "Latte", "Espresso", "Cappuccino"] */
Funktion höherer Ordnung
map
mit Punktnotationlet companies = ["bmw", "kfc", "ibm", "htc"] let uppercasedCompanies = companies.map { (item) -> String in item.uppercased() } /* RESULT: ["BMW", "KFC", "IBM", "HTC"] */
SAN in HOF
map
mit Punktnotationlet uppercasedCompanies = companies.map { $0.uppercased() } /* RESULT: ["BMW", "KFC", "IBM", "HTC"] */
SAN in HOF
filter
mit Restbetreiberlet 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] */
Wiederholen
$0
let cubedNumber = { $0 * $0 * $0 } (25) print(cubedNumber) /* RESULT: 25^3 = 15625 */
Drei Stenografie Argument - Name -
$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 */
Fünf SANs -
$0
,$1
,$2
,$3
und$4
let factorial = { $0 * $1 * $2 * $3 * $4 } (1, 2, 3, 4, 5) print(factorial) /* RESULT: 5! = 120 */
Schlüsselpfadausdruck
In Swift 5.2 können Sie über den Schlüsselpfadausdruck auf Parameter jeder Instanz zugreifen:
struct Lighter { let manufacturer: String let refillable: Bool } let zippo = Lighter(manufacturer: "Zippo", refillable: true) let cricket = Lighter(manufacturer: "Cricket", refillable: false) let lighters: [Lighter] = [zippo, cricket] let refillableOnes = lighters.map(\.refillable) print(refillableOnes) /* RESULT: [true, false] */
Natürlich können Sie alternativ eine bekannte Syntax verwenden:
Regelmäßige Syntax -
$0.property
:let refillableOnes = lighters.map { $0.refillable } print(refillableOnes) /* RESULT: [true, false] */
Kurzargument Name mit einem Index
let arrays: [[String]] = [["Hello", "Hola"], ["world", "mundo"]] let helloWorld = arrays.compactMap { $0[0] } print(helloWorld) /* RESULT: ["Hello", "world"] */
Kurzargumentname im Completion Handler
let completionHandler: (Bool) -> Void = { if $0 { print("It is true, sister...") } }
Die reguläre Syntax lautet jedoch wie folgt:
let completionHandler: (Bool) -> Void = { sayTheTruth in if sayTheTruth { print("It is true, sister...") } }
Swift gegen Kotlin gegen Python
Lassen Sie uns auch sehen, wie Kotlins Lambda Swifts Schließung ähnelt:
Schnell
let element: [String] = ["Argentum","Aurum","Platinum"] let characterCount = element.map { $0.count } print(characterCount) /* RESULT: [8, 5, 8] */
Kotlin
Oft hat Kotlins Lambda-Ausdruck nur einen Parameter mit implizitem Namen :
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] */
quelle
list(map(len, ....))
würde genügen. Persönlich würde ich verwenden, es sei denn, in einem kritischen Leistungsabschnitt,[len(v) for v in ...]
weil es sauberer und besser lesbar ist.Es stellt Kurzargumente dar, die in einen Abschluss gesendet wurden. In diesem Beispiel wird Folgendes aufgeschlüsselt:
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
quelle
add = (+)
var add:((Int, Int) -> Int) = ...
explizit für die Fälle 3 und 4 in meinem schnellen 5-Test angeben .Die beziehen sich auf das erste und zweite Argument der Art. Hier werden
sort
2 Elemente verglichen und sortiert. Weitere Informationen finden Sie in der offiziellen Dokumentation von Swift :quelle
Zusätzlich zu @ Bobbys Antwort möchte ich ein Beispiel hinzufügen
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
quelle
Es handelt sich um Kurzargumentnamen.
Swift stellt Inline-Abschlüssen automatisch Kurzargumentnamen zur Verfügung, mit denen auf die Werte der Argumente des Abschlusses mit den Namen $ 0, $ 1, $ 2 usw. verwiesen werden kann.
Wenn Sie diese Kurzargumentnamen in Ihrem Abschlussausdruck verwenden, können Sie die Argumentliste des Abschlusses in der Definition weglassen, und die Anzahl und der Typ der Kurzargumentnamen werden aus dem erwarteten Funktionstyp abgeleitet. Das Schlüsselwort in kann auch weggelassen werden, da der Abschlussausdruck vollständig aus seinem Körper besteht:
reversed = names.sort( { $0 > $1 } )
Hier beziehen sich $ 0 und $ 1 auf das erste und zweite String-Argument des Abschlusses.
quelle