在Swift中调用函数时,如何链接函数



我是swift的初学者,我正在做练习来学习。

我必须过滤任何偶数,对数组进行排序,将它们映射到字符串,并每行打印一项结果。

问题是,当我调用函数时,我无法链接闭包,它只打印第三个函数。

import Foundation
let luckyNumbers = [7, 4, 38, 21, 16, 15, 12, 33, 31, 49]
func doImportantWorkChain (first: ([Int]) -> [Int], second: ([Int]) -> [Int], third: ([Int]) -> [String]) {
first(luckyNumbers)
second(luckyNumbers)
third(luckyNumbers)
third(luckyNumbers).forEach {
print($0)
}
}
doImportantWorkChain { number in
return number.filter {
return $0.isMultiple(of: 2)
}
} second: { number in
return number.sorted {
return $0 < $1
}
} third: { number in
return number.map {
("($0) is the lucky number")
}
}

输出

7 is the lucky number
4 is the lucky number
38 is the lucky number
21 is the lucky number
16 is the lucky number
15 is the lucky number
12 is the lucky number
33 is the lucky number
31 is the lucky number
49 is the lucky number

输出我必须得到

4 is the lucky number
12 is the lucky number
16 is the lucky number
38 is the lucky number

我知道我必须使用:luckyNumbers.first{}.second{}

当我尝试这样写时,Xcode会给我错误:类型为'([Int](->[Int],([Int](->[Int],([Int](->[String](->(('没有成员'第一个'

所以我先擦除,然后给我这个错误:

"之后应为成员名称

顶级语句不能以闭包表达式开头

类型为"(_(->_"的值没有成员"第二个">

doImportantWorkChain.first{ number in
return number.filter {
return $0.isMultiple(of: 2)
}
}.second{ number in
return number.sorted {
return $0 < $1
}
}.third{ number in
return number.map {
("($0) is the lucky number")
}
}

当我在函数内部调用它们但也不起作用时,我也会尝试将其链接起来。

正如第一个答案所建议的,问题是一个闭包的结果应该在下一个闭包中使用。

获得您想要的输出的最快方法

func doImportantWorkChain(first: ([Int]) -> [Int],
second: ([Int]) -> [Int],
third: ([Int]) -> [String]) {
third(second(first(luckyNumbers))).forEach {
print($0)
}
}

然而,这并不是真正的chaining一起工作,它正在做第一个答案,只是减少了代码行,但这并没有真正的升级。

获得您想要的输出的正确方法(IMO(

我相信其中一位评论者建议直接在luckyNumbers上使用过滤、排序和映射函数来获得您想要的输出:

luckyNumbers
.filter { $0.isMultiple(of: 2) }
.sorted() { return $0 < $1 }
.map { ("($0) is the lucky number") }
.forEach { print($0) }

一种链接的方式,会给你想要的输出,但我不知道你为什么会使用这个

如果你想一想你需要做什么,以实现某种链接,你需要创建你自己的higher order函数,比如filter, map etc,使用与闭包相同的签名,然后执行闭包。

我为Int阵列创建了一个extension

extension Array where Element == Int
{
func apply(_ operation: ([Int]) -> [Int]) -> [Int]
{
return operation(self)
}

func apply(_ operation: ([Int]) -> [String]) -> [String]
{
return operation(self)
}
}

然后你可以实现链接并获得你想要的结果

func doImportantWorkChain(first: ([Int]) -> [Int],
second: ([Int]) -> [Int],
third: ([Int]) -> [String]) {

luckyNumbers
.apply(first)
.apply(second)
.apply(third)
.forEach { print($0) }
}

同样,这可能是一个很好的锻炼你的大脑,探索语言及其能力的练习,但我认为你永远不会真正使用它。

以上三种方式都会给你这个输出:

4 is the lucky number
12 is the lucky number
16 is the lucky number
38 is the lucky number

您没有将前一个函数的结果用于下一个函数。

如果您这样做,那么您将在third(luckyNumbers).forEach行上出现函数预期[Int]的错误,并且您将传递[String]作为此third(luckyNumbers)调用的输出。

要处理此代码,您可以进行以下修改并运行

let luckyNumbers = [7, 4, 38, 21, 16, 15, 12, 33, 31, 49]
func doImportantWorkChain (first: ([Int]) -> [Int], second: ([Int]) -> 
[Int], third: ([Int]) -> [String]) {
let first_result = first(luckyNumbers)
let second_result = second(first_result)
let third_result = third(second_result)
for result in third_result {
print(result)
}
}
doImportantWorkChain { number in
return number.filter {
return $0.isMultiple(of: 2)
}
} second: { number in
return number.sorted {
return $0 < $1
}
} third: { number in
return number.map {
("($0) is the lucky number")
}
}

最新更新