如何将函数作为可选参数传递Swift

3

我刚接触Swift,目前正在尝试将函数作为可选参数传递,方法如下:

import Foundation 

func foo()
{
    print("Foo")
}

func bar()
{
    print("Bar")
}

func dummy()
{
    return
}

func myFunc()
{
    myFunc(callBack: dummy())
}

func myFunc(callBack: (Void))
{
    foo()
    callBack
}

myFunc()
myFunc(callBack: bar())

即利用多态性

这似乎是一种不太优雅的方法,是否有更好的方法?

谢谢, 汤姆

编辑:

我知道可以通过以下方式缩短:

import Foundation 

func foo()
{
    print("Foo")
}

func bar()
{
    print("Bar")
}

func dummy()
{
    return
}

func myFunc(callBack: (Void) = dummy())
{
    foo()
    callBack
}

myFunc()
myFunc(callBack: bar())

但我仍然认为这是一个不太优雅的解决方案。

2
这里的(Void)没有意义,接受空值并返回空值的函数类型应该是() -> Void - user28434'mstep
@Moritz 已记录并修复。 - thoxey
4个回答

10

你可以在参数中轻松定义函数的默认值:

func foo(completion: () -> Void = { }) {
    completion()
}

你也可以将其默认设置为 nil:

func foo(completion: (() -> Void)? = nil) {

当它是一个可选闭包时,您需要像这样调用它:

completion?()

1
我根本猜不到你的意思。不管怎样,我认为这可能是 OP 想要的“优雅”解决方案,所以给个赞。 - kabanus
看起来是这样的,是的。谢谢! - LinusGeffarth
这正是我想要的,我认为它更加“优雅”,谢谢! - thoxey
如何将参数传递给完成处理程序? - Akshat Tiwari
@AkshatTiwari,你可以在函数声明中这样做:completion: (_ x: Int) -> Void = { _ in },然后像这样调用它:completion(5)。我认为这些不接受命名参数。Xcode会帮助你的。 - LinusGeffarth

2

应用答案的完整代码:

import Foundation 

func foo()
{
    print("Foo")
}

func bar()
{
    print("Bar")
}

func myFunc(completion: () -> Void = { })
{
    foo()
    completion()
}

myFunc()
myFunc(completion: bar)

2
你在谈论默认参数

你可以通过在函数中为一个参数赋值来定义该参数的默认值。如果定义了默认值,那么在调用函数时可以省略该参数。

所以你需要类似这样的代码:
func myfunc (callback: ()->void = dummy) {
LinusGeffarth指出,在Swift中,回调被称为完成或者像avismara所说的闭包

1
在Swift中,回调通常被称为“完成”(completion)。 - LinusGeffarth
@LinusGeffarth 我本来想使用OP的命名约定,但我会将您的评论作为问题中的信息添加。 - kabanus
1
@LinusGeffarth 我不确定。除了一些经过充分研究的作业之外,我不喜欢把答案变成教程。我也不确定你到底期望多少辅导 - 如果我的回答不够好,我建议你自己提供答案 - 如果你认为有必要,可以详细说明最佳实践。 - kabanus
1
添加另一个答案有点冗余......的确,OP 显然没有进行任何研究,因为有大量关于完成处理程序的解答。无论如何,如果 OP 正试图找到特定行,而答案只提供他们的代码,则此答案并不真正是一个答案。 - LinusGeffarth
2
我的看法是:在Swift中,它们并不真正被称为completion -- 它们有时基于上下文 -- 但通常被称为closures。 :) - avismara
显示剩余8条评论

1

嗯,你是将函数作为可选参数传递了吗?看起来你编写了一个接受 Void 的方法,你有一个接受 Void 的函数,并且你只是调用了那个方法。我在这里没有看到任何多态的痕迹,除了可能 myFunc 有多个签名之外。这种方法不是因为不优雅而是因为它不是一个解决方案。

这里是函数式系统中多态的正确示例:

func printA() {
    print("A")
}

func printB() {
    print("B")
}

//This method accepts a function as a parameter
func higherOrderPrinter(with print: () -> Void ) { 
    print() //Can be anything, depends on the method you send here. Polymorphism much? :)
}

higherOrderPrinter(with: printA) //Prints A. See carefully how I am NOT doing printA()
higherOrderPrinter(with: printB) //Prints B
//In fact...
higherOrderPrinter {
    print("C") 
} //Prints C

你必须指定并创建一个单独的函数,然后将其传递给参数吗?我找不到一种直接声明函数而不是使用函数名称创建函数的方法。 - chitgoks

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