【问题标题】:Using higher order functions in swift快速使用高阶函数
【发布时间】:2017-06-27 15:27:53
【问题描述】:

我正在学习 swift 来自 Haskell 背景,我想将这一点翻译成 swift:

match :: Int -> Bool
match = (>) 3

hasMatch :: (Int -> Bool) -> [Int] -> [Int]
hasMatch pred ns = filter pred ns

hasMatch match [1..5] = [4,5]

我知道的愚蠢的例子。这就是我使用 swift 所拥有的:

func hasMatch(pred : (Int) -> Bool, ns : [Int]) -> [Int]{
    return ns.filter{n in pred(n:n)}
}


func match(n: Int) -> Bool{
    return n > 3
}

let os = hasMatch(pred : match, ns: [1,2,3,4,5])

不编译。这是错误信息:

let os = hasMatch(pred : match, ns: [1,2,3,4,5])

    ./hello-swift.swift:48:28: error: extraneous argument label 'n:' in call
        return ns.filter{n in pred(n:n)}
                                  ^~~

./hello-swift.swift:48:24: error: closure use of non-escaping parameter 'pred' may allow it to escape
        return ns.filter{n in pred(n:n)}
                              ^
./hello-swift.swift:47:15: note: parameter 'pred' is implicitly non-escaping
func hasMatch(pred : (Int) -> Bool, ns : [Int]) -> [Int]{
              ^
                     @escaping 

我有两个问题:

  1. 我有pred(n:n),但这假设pred 将其输入命名为n,这没有意义。所有函数都必须有命名输入吗?

  2. 如何更改代码以便编译

【问题讨论】:

标签: ios swift haskell


【解决方案1】:
func hasMatch(pred: (Int) -> Bool, ns: [Int]) -> [Int] {
    return ns.filter { n in pred(n) }
}

如果函数是闭包,则不需要参数名称。

@escaping 是 swift 中的一个关键字,它告诉编译器传入的函数将转义当前作用域,因此它需要保留/释放传入的参数(Swift 和 Objective-c 一样,使用保留计数来计算内存管理)

但是,在这种情况下您不需要它 - 该错误是编译器抛出的红鲱鱼,因为它无法编译带有 filter 的行,所以它不知道您是否需要转义或不。看起来它很安全:)

一旦您删除 n: 并且它可以确定您正在调用哪个 filter,它就知道因为 filter 不需要 @escaping 闭包,您的方法也不需要这样错误消失。

【讨论】:

  • @MartinR 刚刚意识到 - 看看我的编辑!认为它看起来不对,但我无法说出原因。这将教会我盲目地遵循 Xcode 中的自动修复按钮!
  • @Martin R 很抱歉,如果函数是闭包,您能解释一下为什么我不需要参数名称吗?我对整个参数名称的事情感到非常困惑。
  • @chibro2:这是github.com/apple/swift-evolution/blob/master/proposals/… 的结果。看看我上面链接到的两个问答。
【解决方案2】:
func mapedData(){
let bookData = ["book1":120, "book2": 150]
let mapedData = bookData.map({(key,value) in return value + 40 })
print(mapedData)
}

// [160, 190]

func filterData()
{
     let bookData = ["book1":127, "book2": 150 ,"book3": 289 ,"book4": 190, "book5": 950  ]
    let filterData = bookData.filter({(key,value) in return value < 200})
    print(filterData)
}

// ["book2": 150, "book4": 190, "book1": 127]

func reducedData()
{
    let data = [1,2,3,4,5,6,7,8,9,10]
    let reducedData = data.reduce(0, { sum , number in return sum + number })
    print(reducedData)
}

//55

func compactData(){
       let data = [1,nil,3,4,5,6,7,nil,9,10]
    let cMap = data.compactMap({return $0})
    print(cMap)
}
// [1, 3, 4, 5, 6, 7, 9, 10]

func flatMappedData(){
    let data = ["sachin"]
    let characters = data.flatMap({return $0})
    print(characters)        
}

// ["s", "a", "c", "h", "i", "n"]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-03
    • 2016-05-07
    相关资源
    最近更新 更多