在SWIFT结算中,0美元和1美元意味着什么?

iih3973s  于 2022-10-23  发布在  Swift
关注(0)|答案(7)|浏览(144)
let sortedNumbers = numbers.sort { $0 > $1 }
print(sortedNumbers)

谁能解释一下,$0$1在swft中是什么意思?
更多样本

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

inn6fuwd1#

$0是传递到闭包中的第一个参数。$1是第二个参数,依此类推。

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

qco9c6ql2#

TL;DR

SWIFT 5.7

$0$1是闭包的第一个和第二个速记参数名称(简称SAN)或隐式参数名称。速记参数名称由SWIFT自动提供。第一个参数被**$0引用,第二个参数被**$1引用,第三个参数被$2**引用,依此类推。

如您所知,Closure是一个自包含的功能块(没有名称的函数),可以在代码中传递和使用。闭包在其他编程语言中有不同的名称,含义也略有不同--在Python和Kotlin中是Lambda,在C和Objective-C中是Block

缩短封闭期

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 { 
    (n1: String, n2: String) -> Bool in return n1 > n2 
}

3.隐式返回的闭包从上下文推断类型

reverseOrder = coffee.sorted { n1, n2 in n1 > n2 }

4.速记参数名称

reverseOrder = coffee.sorted { $0 > $1 }

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

5.运算符方法

reverseOrder = coffee.sorted(by: >)

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

带闭包的高阶函数

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

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

print(uppercased)

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

速记参数名称$0

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

print(uppercased)

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

带余数运算符的完整闭包表达式(又名模数)

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

let filteredNumbers = numbers.filter { 
    (arg: Int) -> Bool in return (arg % 2) == 0 
}

print(filteredNumbers)

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

带余数运算符的速记参数名

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

变量函数是接受任意数量的参数的函数。最著名的变分方法之一是print(...)。速记参数名称非常适合各种函数。

fileprivate func dessert(_ fruits: String...) -> Bool {

    return fruits.contains { $0 == "Apple" }
}

let contains = dessert("Mango", "Durian", "Papaya")

print(contains)

/* RESULT:  false */

存在序列类型$0

这里,allSatisfy()方法指示序列的每个元素是否满足给定的 predicate 。Any类型表示任何类型的值。存在的any类型用于存储符合特定协议的任何类型的值。另外,我在这里使用了可选绑定(跟踪现有常量)的简写语法。

let inputData: [Any]? = [1, 2, 3, "Hello"]

func satisfiesOrNot(_ inputData: any Sequence) -> Bool {
    inputData.allSatisfy { $0 is Int }
}

if let inputData {
    satisfiesOrNot(inputData)
}

/* RESULT:  false */

重复$0

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

print(cubedNumber)

/* RESULT:  25^3 = 15625 */

闭包捕获$0

如果您在闭包内使用外部值,则SWIFT会捕获它们。

func trainer(_ said: String) -> (String) -> String {
    return {
        return "¡\(said) \($0)!"
    }
}

let announcement = trainer("Bienvenido a mis cursos")
announcement("RealityKit 2022")

/* RESULT:  "¡Bienvenido a mis cursos RealityKit 2022!"  */

速记参数名称$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 */

sans$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] */

带下标的SAN

(如果你想知道如何在数组中实现negative indexing,请阅读这篇文章。)

let arrays: [[String]] = [["Hello","Hola","你好"], ["world","mundo","世界"]]

let helloWorld = arrays.compactMap { $0[0] }

print(helloWorld)

/* RESULT:  ["Hello", "world"] */

另一个带有key快捷方式(SWIFT 5.6)和下标的示例:

let dictionaries: [[_ : Any?]] = [[1: "x"], [2: nil], [3: true]]

let values = dictionaries.compactMap { $0[$0.startIndex].value }

print(values) 

/* RESULT:  ["x", true] */

或者看看无序集合的例子:

let collection: Set<String> = ["One", "", "Three"]

collection.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"    */

完成处理程序中的SAN

let completionHandler: ((Bool) -> Void)? = {
    if $0 {
        print("It is true, sister...")
    } else {
        print("False")
    }
}
completionHandler?(true)

/* RESULT:  It is true, sister... */

但是,常规语法如下所示:

let completionHandler: ((Bool) -> Void)? = { sayTheTruth in
    if sayTheTruth {
        print("It is true, sister...")
    } else {
        print("False")
    }
}
completionHandler?(false)

/* RESULT:  False */

SAN in Form 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  */

运营商方式VS SAN

操作员方法:

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 */

速记参数名称$0和$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 */

取值为$0

当SwiftUI手势更改或结束时,.onChanged.onEnded修饰符执行*@转义闭包*。

@State private var rotate: Angle = .zero

var myGesture: some Gesture {
    RotationGesture()
        .onChanged { rotate = $0 }
        .onEnded { angle in rotate = angle }
}

var body: some View {
    Rectangle()
        .rotationEffect(rotate)
        .gesture(myGesture)
}

SWIFT VSKotlinVS PYTHON

另外,让我们看看Kotlin的lambda与Swift的闭合有什么相似之处:

SWIFT

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

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

print(characterCount)

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

柯特林
Kotlin的lambda表达式只有一个隐式名称的参数:it。换句话说,如果您的函数文本只有一个参数,则不需要显式定义该参数,您可以改用it(就像SWIFT中的$0)。

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]
ulmd4ohb

ulmd4ohb3#

它表示发送到闭包中的人手不足的参数,本例对其进行了分解:

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
svgewumm

svgewumm4#

指的是排序的第一个和第二个参数。在这里,sort比较两个元素并对它们进行排序。您可以在Swift official documentation上查找更多信息:
SWIFT自动为内联闭包提供简写参数名称,可用于通过名称$0、$1、$2等引用闭包参数的值。

jk9hmnmh

jk9hmnmh5#

除了@Bobby的回答,我还想加一个例子

var add: (Int,Int,Int)->Int
add = {
//So here the $0 is first argument $1 is second argument $2 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
50pmv0ei

50pmv0ei6#

它是参数的速记名称。
SWIFT自动为内联闭包提供简写参数名称,可用于通过名称$0、$1、$2等引用闭包参数的值。
如果在闭包表达式中使用这些速记参数名称,则可以从其定义中省略闭包的参数列表,并且速记参数名称的数量和类型将从预期的函数类型中推断出来。也可以省略in关键字,因为闭包表达式完全由其正文组成:

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

这里,$0和$1指的是闭包的第一个和第二个字符串参数。

dffbzjpn

dffbzjpn7#

$0$1,等表示在集合上执行操作时的项。
例如,要打印数字列表,可以使用内置的forEach()函数和$0,如下所示:

let numbers = [1, 2, 3, 4, 5]
numbers.forEach { print($0) }

这里,$0一次表示数组中的每个数字。
SWIFT中的🛑**$0和$1**
在解释什么是$0$1之前,让我们先看一个例子。
假设您有一个数字数组,并且想要打印它们。您可以使用for循环来完成此操作:

let numbers = [1, 2, 3, 4, 5]
for number in numbers {
    print(number)
}

但是,还有另一种使用forEach$0的替代方法:

numbers.forEach { print($0) }

让我们检查一下代码,看看它有什么作用:

  • 它接受numbers数组并调用forEach来运行数组中的代码for each number元素。
  • forEach方法接受带有数字参数的闭包。在本例中,闭包是{ print($0) }。对数组中的每个数字逐个调用此闭包。
  • 每次调用时,$0表示来自numbers数组的不同数字参数。

🛑更详细的解释
让我们创建一个闭包,并将其赋给一个名为printer的变量。此闭包将一个数字作为其参数并打印出来:

var printer = { (n: Int) -> Void in
    print(n)
}
// Test calling printer closure on a number 3 for example:
printer(3) // prints 3 - it works
// Now, use printer to print numbers (from the previous example):
numbers.forEach(printer) // prints 1, 2, 3, 4, 5

您可以简化这个闭包:最后,使用这个闭包打印一个整数数组。因此,SWIFT可以自动推断参数类型(整型),而无需明确指定。因此,printer可以简化为:

printer = { n in
    print(n)
}
// Test: printing numbers still works:
numbers.forEach(printer) // prints 1, 2, 3, 4, 5

现在,这就是$0的用武之地:在SWIFT中,也可以省略闭包中的参数名。在执行此操作时,可以使用$0$1$2引用省略的参数。让我们通过省略数字参数来简化打印机关闭:

printer = { print($0) }
// forEach accepts a closure:
numbers.forEach(printer) // prints 1, 2, 3, 4, 5

最后,没有什么可以强迫您将printer赋给一个名为printer的变量。您可以匿名使用闭包来实现相同的行为:

numbers.forEach { print($0) } // prints 1, 2, 3, 4, 5

这就是你之前看到的那条线。
创建一个数组,其中Numbers数组中的所有numbers都使用map方法进行二次幂运算。

let numbers = [1, 2, 3, 4, 5]
let pow_nums = numbers.map { $0 * $0 }
pow_nums.forEach { print($0) } // Prints 1, 4, 9, 16, 25

Code Happy;)

相关问题