【问题标题】:How to create higher order functions in Swift?如何在 Swift 中创建高阶函数?
【发布时间】:2018-06-03 23:39:58
【问题描述】:

我遇到了数组forEach 函数,它是一个高阶函数,它只需要一个参数,,一个闭包。现在这个闭包在内部循环遍历数组的所有元素,但不返回任何内容。闭包的实现留给用户选择。

我有一个自定义类 MyClass,其中有一个私有变量 num 和一个公共函数 setNum(num: Int) 从外部设置该私有变量的值。我只是想在我的自定义类中创建一个类似的函数factorial,它只接受一个参数,,一个闭包。但是,我必须手动调用factorial 内部的闭包,将num 的值作为参数传递给闭包。

有没有一种方法可以使闭包对num 起作用而无需将其作为参数传递?基本上我只是想复制数组forEach 函数。数组forEach的语法是:

array.forEach(body: (Int) -> Void) -> Void)

实施:

arr1.forEach { print($0) }

我的代码如下:

import Foundation

public class MyClass {
    private var factorialNumber: Double = 0
    internal static var instance: MyClass?

    public func setFactorialNumber(number value: Double) {
        factorialNumber = value
    }

    public func factorial(body closure: (String?) -> Void) -> Void {
        var outputString: String?
        var result: Double = 1

        if factorialNumber <= 0 {
            outputString = nil
        } else {
            outputString = ""
            while(factorialNumber >= 1) {
                if factorialNumber == 1 {
                    outputString = outputString! +  "\(factorialNumber) = \(result)"
                    break
                } else {
                    outputString = outputString! + "\(factorialNumber) x "
                }
                result = result * factorialNumber
                factorialNumber -= 1
            }
        }

        // Finally closure call
        closure(outputString)
    }

    private init() {}

    public static func getInstance() -> MyClass {
        if self.instance == nil {
            self.instance = MyClass()
        }
        return self.instance!
    }
}

这就是我必须如何调用我的函数来计算阶乘:

var obj1 = MyClass.getInstance()

obj1.setFactorialNumber(number: 5)
obj1.factorial{ (result) in
    print(result ?? "Factorial Result is Nil")
}

请注意,我必须在我的闭包中传递一个参数 result 才能得到阶乘的结果。

【问题讨论】:

  • 使用闭包来计算阶乘是没有意义的。 ArrayforEach 函数与您对 factorial 的需求毫无共同之处。
  • 你不想减少而不是 foreach 吗? developer.apple.com/documentation/swift/array/2298686-reduce
  • @vermau 您提到了MyClassMyArray,但看起来它们是一回事。看来MyClass 是一个错字,应该是MyArray。然后MyArray 是一个非常糟糕的类名称,因为该类与数组无关。
  • 我不太清楚这个问题。你说“我要做的就是学习如何创建像 array.forEach 这样的高阶函数。”但你已经做到了。 factorial 不是“像 array.forEach 这样的高阶函数”怎么样?你想要什么调用语法而不是你提供的调用语法?
  • "... 在 array.forEach 函数中,没有传递给闭包的参数。" – 我不确定你的意思。 arr1.forEach { print($0) }arr1.forEach { (elem) in print(elem) } 的简写,elem 是传递给闭包的参数。

标签: swift closures


【解决方案1】:

有没有一种方法可以使闭包在不将其作为参数传递的情况下对 num 起作用?基本上我只是想复制数组forEach 函数... [而且,在你的评论中:] 我要做的就是学习如何创建像array.forEach 这样的高阶函数。

很难理解你认为你在追求什么,但相信你的话,让我们写forEach。我们开始:

extension Sequence {
    func myForEach(f: (Element) -> ()) {
        for e in self {
            f(e)
        }
    }
}

让我们测试一下:

[1,2,3].myForEach { print($0) } // prints 1, then 2, then 3

我们做到了!我们编写了一个与forEach 完全一样的高阶函数。所以这一定是forEach 实际工作的方式,或多或少。

您可以从示例中看到,要求不必将参数传递给我们的forEach 作为参数的函数是没有意义的。这正是我们必须能够使该函数具有可操作的元素的能力。

【讨论】:

  • 非常感谢马特的解释。我在“阶乘”函数中也做同样的事情。然后当我从代码中调用“阶乘”时,为什么我必须通过“结果”来获取输出并将其打印在屏幕上。为什么我不能使用 $0 来打印输出。我希望我的函数是这样的: obj1.factorial { print("Factorial is: ($0)") } 但我必须写: obj1.factorial { (result) in print("Factorial is: (result)") }
  • 那就写吧。毕竟,result in ... result$0 只是说同一件事的两种方式。在我看来,您只是忘记了反斜杠。 obj1.factorial { print("Factorial is: \($0)") }
  • 嗨,马特,非常感谢您的帮助。它得到了解决。再次感谢您。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-06-23
  • 2015-06-25
  • 1970-01-01
  • 2020-04-29
  • 1970-01-01
  • 2014-11-04
  • 1970-01-01
相关资源
最近更新 更多