let sortedNumbers = numbers.sort { $0 > $1 }
print(sortedNumbers)
Хто-небудь може пояснити, що $0
і що $1
означає швидко?
Більше зразка
array.forEach {
actions.append($0)
}
let sortedNumbers = numbers.sort { $0 > $1 }
print(sortedNumbers)
Хто-небудь може пояснити, що $0
і що $1
означає швидко?
Більше зразка
array.forEach {
actions.append($0)
}
Відповіді:
$0
- це перший параметр, який передається в закриття. $1
це другий параметр і т. д. Це закриття, яке ви показали, є скороченням для:
let sortedNumbers = numbers.sort { (firstObject, secondObject) in
return firstObject > secondObject
}
$0
і$1
є першим і другим скорочувальними аргументами Закриття (він жеShorthand Argument Names
абоSAN
скорочено). Імена скорочених аргументів автоматично надаються Swift. На перший аргумент можна посилатись$0
, на другий аргумент можна посилатися$1
, на третій -$2
тощо.
Як ви знаєте, Закриття - це самостійний блок функціональних можливостей (функція без імені), який можна передавати та використовувати у коді. Закриття має різні назви в інших мовах програмування, а також незначні відмінності у значенні - це Лямбда на Python та Kotlin або Блок на C та Objective-C .
let coffee: [String] = ["Cappuccino", "Espresso", "Latte", "Ristretto"]
1. Нормальна функція
func backward(_ n1: String, _ n2: String) -> Bool {
return n1 > n2
}
var reverseOrder = coffee.sorted(by: backward)
/* RESULT: ["Ristretto", "Latte", "Espresso", "Cappuccino"] */
2. Вбудований вираз закриття
reverseOrder = coffee.sorted(by: { (n1: String,
n2: String) -> Bool in return n1 > n2 } )
3. Висновок типу з контексту
reverseOrder = coffee.sorted(by: { n1, n2 in return n1 > n2 } )
4. Неявна повернення із закритих виразів
reverseOrder = coffee.sorted(by: { n1, n2 in n1 > n2 } )
5. Стенографічні назви аргументів
reverseOrder = coffee.sorted(by: { $0 > $1 } )
/* $0 and $1 are closure’s first and second String arguments. */
6. Методи оператора
reverseOrder = coffee.sorted(by: >)
/* RESULT: ["Ristretto", "Latte", "Espresso", "Cappuccino"] */
map
з крапковим позначеннямlet companies = ["bmw", "kfc", "ibm", "htc"]
let uppercasedCompanies = companies.map { (item) -> String in item.uppercased() }
/* RESULT: ["BMW", "KFC", "IBM", "HTC"] */
map
форматі HOF із крапковим позначеннямlet uppercasedCompanies = companies.map { $0.uppercased() }
/* RESULT: ["BMW", "KFC", "IBM", "HTC"] */
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] */
$0
let cubedNumber = { $0 * $0 * $0 } (25)
print(cubedNumber)
/* RESULT: 25^3 = 15625 */
$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 */
$0
, $1
, $2
, $3
і$4
let factorial = { $0 * $1 * $2 * $3 * $4 } (1, 2, 3, 4, 5)
print(factorial)
/* RESULT: 5! = 120 */
У Swift 5.2 ви можете отримати доступ до параметрів кожного екземпляра за допомогою виразу шляху шляху:
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] */
Звичайно, ви можете використати знайомий синтаксис:
Регулярний синтаксис -$0.property
:
let refillableOnes = lighters.map { $0.refillable }
print(refillableOnes)
/* RESULT: [true, false] */
let arrays: [[String]] = [["Hello", "Hola"], ["world", "mundo"]]
let helloWorld = arrays.compactMap { $0[0] }
print(helloWorld)
/* RESULT: ["Hello", "world"] */
let completionHandler: (Bool) -> Void = {
if $0 {
print("It is true, sister...")
}
}
Однак регулярний синтаксис такий:
let completionHandler: (Bool) -> Void = { sayTheTruth in
if sayTheTruth {
print("It is true, sister...")
}
}
Крім того, давайте подивимось, як лямбда Котліна схожа на закриття Свіфта:
Стрімкий
let element: [String] = ["Argentum","Aurum","Platinum"]
let characterCount = element.map { $0.count }
print(characterCount)
/* RESULT: [8, 5, 8] */
Котлін
Часто лямбда - вираз Котлин має тільки один параметр з ім'ям неявного: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] */
list(map(len, ....))
вистачило б. Особисто я б використовував хіба що в критичному розділі продуктивності, [len(v) for v in ...]
оскільки він чистіший і читабельніший.
Він представляє скорочені аргументи, надіслані в закриття, цей приклад розбиває його:
Свіфт 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
add = (+)
var add:((Int, Int) -> Int) = ...
випадками 3 та 4, у моєму швидкому тесті 5.
Посилання на перший та другий аргументи сортування. Тут sort
порівнюються 2 елементи та їх порядок. Ви можете переглянути офіційну документацію Swift для отримання додаткової інформації:
Swift автоматично надає скорочені імена аргументів для вбудованих закриттів, які можуть використовуватися для посилання на значення аргументів закриття за іменами $ 0, $ 1, $ 2 тощо.
Окрім відповіді @ Bobby, я хотів би додати приклад
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
Це скорочені назви аргументів.
Swift автоматично надає скорочені імена аргументів для вбудованих закриттів, які можуть використовуватися для посилання на значення аргументів закриття за іменами $ 0, $ 1, $ 2 тощо.
Якщо ви використовуєте ці скорочені імена аргументів у своєму виразі закриття, ви можете опустити список аргументів закриття з його визначення, а кількість та тип імен скорочених аргументів будуть виведені з очікуваного типу функції. Ключове слово in також можна пропустити, оскільки вираз закриття складається повністю з його тіла:
reversed = names.sort( { $0 > $1 } )
Тут $ 0 та $ 1 відносяться до першого та другого аргументів рядка закриття.