如何在Swift 3中将一个函数设置为函数参数

3

Q: 在Swift 3中,是否可以将函数作为函数参数传递?

为了重构我的代码,我想要一个全局函数。在这个函数的结尾,有一个具有action参数的自定义按钮。

let deleteButton = MIAlertController.Button(title: "cancel", 
                                            type: .cancel, 
                                            config: getDestructiveButtonConfig(),
                                            action: {
                                                print("completed")
                                            })

我想要做的是,设置一个带有函数参数的全局函数。
MyGlobalStuff.swift
...
func getButton(_ myFunc: func, _ title: String) {
    let deleteButton = MIAlertController.Button(title: title, 
                                            type: .cancel, 
                                            config: getDestructiveButtonConfig(),
                                            action: {
                                                myFunc // call here the function pass by argument
                                            })
}

getButton(..) 在同一类中使用传递的函数调用。

MyViewController.swift
...
getButton(myPrintFunc, "cancel")

func myPrintFunc() {
        print("completed")
}

有类似这样的可能性吗?非常感谢您的帮助。

@Santosh你提供的链接并没有解决我的问题。我不是在寻找闭包或返回值。 - David Seek
好的。实际上我需要一个闭包……我发誓,我之前尝试过了,但没有成功。在看到答案后又尝试了一次,成功了……是我的问题。谢谢你的时间。 - David Seek
3个回答

14

是的,你可以将一个函数/闭包作为另一个函数的参数传递。

这是语法:

func doSomething(closure: () -> ()) {
    closure()
}

这里的函数doSomething的参数是一个不带参数和返回类型的闭包。

你可以使用以下语法调用doSomething:

doSomething(closure: { _ in print("Hello world") })

或者使用尾随闭包语法

doSomething { 
    print("Hello world")
}

闭包不起作用,因为一旦调用了getButton函数,这段代码就会立即被调用,而不是在按钮被按下后才执行。 - David Seek
2
@DavidSeek,为什么一旦调用getButton函数就会立即执行它? - user28434'mstep
如果我在getButton中有一个闭包,它将在函数完成时立即被调用。但是我需要它在按钮被按下后才被调用。 - David Seek
2
你把它放在了 MIAlertController.Buttonaction 参数里吗? - user28434'mstep
好的,已经搞定了。之前尝试使用闭包,但是没有成功。我猜是我的问题。另外,我认为你的方法和Luke的方法是一样的?_ myFunc: () -> Void_ closure: () -> () 是相同的。 - David Seek

10

假设

typealias Func = () -> Void    

您可以做:

func getButton(_ title: String, _ myFunc: Func) {
    let deleteButton = MIAlertController.Button(title: title, 
                                                type: .cancel, 
                                                config: getDestructiveButtonConfig(),
                                                action: {
                                                    myFunc()
                                                })
}

甚至是:

func getButton(_ title: String, _ myFunc: Func) {
    let deleteButton = MIAlertController.Button(title: title, 
                                                type: .cancel, 
                                                config: getDestructiveButtonConfig(),
                                                action: myFunc
                                                )
}

另外,如果您没有注意到,我将闭包移动到参数列表的末尾。这样做将允许高级魔法,例如:

getButton("X") { … }

代替

getButton({ … }, "X")

嗯,我喜欢typealias。谢谢!点赞支持。 - David Seek

6

在Swift中,函数是第一类对象,因此您可以像这样传递它们:

func getButton(_ myFunc: () -> Void, _ title: String) {

您需要在类型中指定函数的签名,即参数类型和返回类型。


谢谢,你的方法和AppzYourLife一样好用。因为他更快,所以我会给他打勾。感谢你的时间和帮助,我会点赞的。谢谢。 - David Seek

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接