Kan iemand uitleggen wat $0
en $1
betekenen in swift?
Meer voorbeeld
array.forEach {
actions.append($0)
}
Antwoord 1, autoriteit 100%
$0
is de eerste parameter die in de sluiting wordt doorgegeven. $1
is de tweede parameter, enz. De sluiting die je liet zien is een afkorting voor:
let sortedNumbers = numbers.sort { (firstObject, secondObject) in
return firstObject > secondObject
}
Antwoord 2, autoriteit 50%
TL;DR
Snelle 5.5
$0
en$1
zijn de eerste en tweede steno-argumenten van Closure(ook bekend alsShorthand Argument Names
ofSAN
in het kort). De steno-argumentnamen worden automatisch geleverd door Swift. Naar het eerste argument kan worden verwezen door$0
, naar het tweede argument kan worden verwezen door$1
, naar het derde door$2
, enzovoort.
Zoals u weet, is een Sluitingeen op zichzelf staand blok van functionaliteit (een functie zonder naam) die kan worden doorgegeven en gebruikt in uw code. Sluiting heeft verschillende namen in andere programmeertalen en ook kleine verschillen in betekenis – het is Lambdain Python en Kotlin, of Blockin C en Obj-C.
Een sluiting inkorten
let coffee: [String] = ["Cappuccino", "Espresso", "Latte", "Ristretto"]
1. Normale functie
func backward(_ n1: String, _ n2: String) -> Bool {
return n1 > n2
}
var reverseOrder = coffee.sorted(by: backward)
/* RESULT: ["Ristretto", "Latte", "Espresso", "Cappuccino"] */
2. Inline sluitingsuitdrukking
reverseOrder = coffee.sorted(by: { (n1: String,
n2: String) -> Bool in return n1 > n2 } )
3. Type afleiden uit context
reverseOrder = coffee.sorted(by: { n1, n2 in return n1 > n2 } )
4. Impliciete opbrengst van sluitingen met één expressie
reverseOrder = coffee.sorted(by: { n1, n2 in n1 > n2 } )
5. Namen van steno-argumenten
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"] */
Hogere orde functie map
met puntnotatie
let companies = ["bmw", "kfc", "ibm", "htc"]
let uppercased = companies.map { (item) -> String in item.uppercased() }
/* RESULT: ["BMW", "KFC", "IBM", "HTC"] */
Shorthand Argumentnaam in HOF map
let uppercased = companies.map { $0.uppercased() }
/* RESULT: ["BMW", "KFC", "IBM", "HTC"] */
SAN in HOF filter
met operator voor rest
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] */
SAN in Variadische functies
Variadische functies zijn functies die een willekeurig aantal parameters accepteren. Verkorte argumentnamen zijn perfect voor dergelijke gevallen.
fileprivate func dessert(_ fruits: String...) -> Bool {
return fruits.contains { $0 == "Apple" }
}
let contains = dessert("Mango", "Durian", "apple")
print(contains)
/* RESULT: false */
Herhalen van $0
let cubedNumber = { $0 * $0 * $0 } (25)
print(cubedNumber)
/* RESULT: 25^3 = 15625 */
Drie steno-argumentnamen – $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 */
Vijf SAN’s – $0
, $1
, $2
, $3
, $4
let factorial = { $0 * $1 * $2 * $3 * $4 } (1, 2, 3, 4, 5)
print(factorial)
/* RESULT: 5! = 120 */
Toetsenpadexpressie
In Swift 5.2 hebt u toegang tot parameters van elke instantie via sleutelpadexpressie:
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] */
Natuurlijk kunt u ook een bekende syntaxis gebruiken:
Gewone syntaxis – $0.property
:
let refillableOnes = lighters.map { $0.refillable }
print(refillableOnes)
/* RESULT: [true, false] */
Shorthand Argumentnaam met een subscript
let arrays: [[String]] = [["Hello", "Hola"], ["world", "mundo"]]
let helloWorld = arrays.compactMap { $0[0] }
print(helloWorld)
/* RESULT: ["Hello", "world"] */
Nog een voorbeeld met een subscript:
let dictionaries: [[Int8: Any?]] = [[1: "x"], [2: nil], [3: "z"]]
let values = dictionaries.compactMap { $0[$0.startIndex].value }
print(values)
/* RESULT: ["x", "z"] */
Of bekijk dit voorbeeld:
let sett: Set<String> = ["One", "", "Three"]
sett.map {
switch $0.isEmpty {
case true:
print("Empty")
case false:
print("Element \($0) isn't empty")
}
}
/* RESULT: "Element Three isn't empty" */
/* "Empty" */
/* "Element One isn't empty" */
Shorthand-argumentnaam in voltooiingshandler
let completionHandler: ((Bool) -> Void)? = {
if $0 {
print("It is true, sister...")
} else {
print("False")
}
}
completionHandler?(true)
/* RESULT: It is true, sister... */
De normale syntaxis is echter als volgt:
let completionHandler: ((Bool) -> Void)? = { sayTheTruth in
if sayTheTruth {
print("It is true, sister...")
} else {
print("False")
}
}
completionHandler?(false)
/* RESULT: False */
SAN in ForEach-structuur in SwiftUI
let columns: [GridItem] = Array(repeating: .init(.fixed(70)), count: 5)
var body: some View {
ScrollView {
LazyVGrid(columns: columns) {
ForEach((1...10), id: \.self) {
Text("\($0)").frame(maxWidth: .infinity)
}
}
}
}
/* RESULT: 1 2 3 4 5 */
/* 6 7 8 9 10 */
Operatormethode versus SAN
Operatormethode:
let records: [Int] = [110, 108, 107, 109, 108]
public func averageSpeed(records: [Int]) throws -> Int {
let average = records.reduce(0, +) / records.count
return average
}
try averageSpeed(records: records)
/* RESULT: 108 */
Shorthand-argumentnamen $0 en $1:
public func averageSpeed(records: [Int]) throws -> Int {
let average = records.reduce(0) { $0 + $1 } / records.count
return average
}
try averageSpeed(records: records)
/* RESULT: 108 */
Swift vs Kotlin vs Python
Laten we ook eens kijken hoe de lambda van Kotlin lijkt op de sluiting van Swift:
Snel
let element: [String] = ["Argentum","Aurum","Platinum"]
let characterCount = element.map { $0.count }
print(characterCount)
/* RESULT: [8, 5, 8] */
Kotlin
Vaak heeft de lambda-expressie van Kotlin maar één parameter met een impliciete naam: 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]
Antwoord 3, autoriteit 23%
Het vertegenwoordigt shorthanded argumenten die naar een afsluiting zijn gestuurd, dit voorbeeld splitst het op:
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
Antwoord 4, autoriteit 4%
De verwijzen naar de eerste en tweede soort argumenten. Hier vergelijkt sort
2 elementen en rangschikt ze.
Je kunt Swift officiële documentatieopzoeken voor meer informatie info:
Swift geeft automatisch namen van steno-argumenten aan inline
sluitingen, die kunnen worden gebruikt om te verwijzen naar de waarden van de sluitingen
argumenten met de namen $0, $1, $2, enzovoort.
Antwoord 5, autoriteit 3%
Aanvullend op @Bobby’s antwoord wil ik graag een voorbeeld toevoegen
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
Antwoord 6
Het zijn verkorte argumentnamen.
Swift geeft automatisch steno-argumentnamen aan inline-afsluitingen, die kunnen worden gebruikt om naar de waarden van de argumenten van de afsluiting te verwijzen met de namen $0, $1, $2, enzovoort.
Als u deze steno-argumentnamen gebruikt in uw sluitingsuitdrukking, kunt u de lijst met argumenten van de sluiting weglaten uit de definitie, en het aantal en type van de steno-argumentnamen worden afgeleid uit het verwachte functietype. Het sleutelwoord in kan ook worden weggelaten, omdat de sluitingsexpressie volledig uit de body bestaat:
reversed = names.sort( { $0 > $1 } )
Hier verwijzen $0 en $1 naar de eerste en tweede String-argumenten van de sluiting.