如何在Swift中创建更高阶的函数?

时间:2018-06-03 23:39:58

标签: swift closures

我遇到了数组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以获得因子的结果。

1 个答案:

答案 0 :(得分:1)

  

有没有一种方法可以在不将参数作为参数传递的情况下对闭包进行操作?基本上我只是试图复制数组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作为参数的函数是没有意义的。这正是我们必须能够做的事情,以便该函数有一个元素可以操作。