回调方法是什么?

27

我是一个编程新手,不太理解回调方法的概念。尝试在维基百科上阅读了相关内容,但没看懂。请有人以简单易懂的方式解释一下吗?

7个回答

23

回调函数是一种传递给函数的东西,告诉它在执行操作的某个时刻应该调用什么。函数中的代码决定何时调用该函数(以及传递哪些参数)。通常情况下,在支持函数对象的语言中,你会将函数本身作为“回调”传递。在其他语言中,可能需要传递某种特殊的东西,如“函数指针”(或类似的东西);或者需要传递函数的名称(然后在运行时进行查找)。

以下是 Python 中的一个简单例子:

void call_something_three_times(what_to_call, what_to_pass_it):
    for i in xrange(3): what_to_call(what_to_pass_it)

# Write "Hi mom" three times, using a callback.
call_something_three_times(sys.stdout.write, "Hi mom\n")

这个例子让我们将重复调用函数的任务与实际调用函数的任务分开。虽然这没有什么用处,但它演示了这个概念。

在现实世界中,回调函数经常用于像线程库这样的东西,其中您使用一个描述线程将要执行的工作的回调函数来调用某个创建线程的函数。线程创建函数完成设置线程所需的工作,然后安排新线程调用回调函数。


13

维基百科说:

在计算机编程中,回调是指向可执行代码或一部分可执行代码的引用,这些代码作为参数传递给其他代码。这允许较低级别的软件层调用在较高级别的层中定义的子例程(或函数)。

通俗来说,回调是一种通知代码块(例如方法)在需要时要执行哪个代码块(即另一个方法)的机制。
回调与调用函数的客户端指定一个属于客户端代码责任的函数有关,并将其作为参数传递给调用函数以执行。
GUI界面中就有一个例子。您将要调用的函数作为参数传递,以便在事件发生(例如按下按钮)时调用该函数。
这个函数通常由最初注册事件的对象实现。


6
回调函数是通过函数指针调用的函数。如果您将一个函数的指针(地址)作为参数传递给另一个函数,当使用该指针调用它所指向的函数时,就会发生回调。 为什么要使用回调函数? 回调可用于通知。例如,您需要在应用程序中设置定时器。每次定时器到期时,必须通知您的应用程序。但是,时间机制的实现者对您的应用程序一无所知。它只想要一个具有给定原型的函数指针,并在使用该指针时进行回调,通知您的应用程序已发生的事件。实际上,SetTimer() WinAPI使用回调函数来通知定时器已到期(如果未提供回调函数,则会将消息发布到应用程序的队列)。

3
任何支持回调的语言都会以某种形式拥有函数指针,它可能隐藏在接口或虚函数后面,并被重载、覆盖(或者是其他语言设计者想要称呼它的方式)函数掩盖,但无论如何,在某个地方,将会有一个“跳转”或“调用”命令,它的目标来源于 RAM 中的变量,而不是硬编码在汇编(无论是 VM 的“汇编”代码还是 CPU 汇编代码)中。 - Grant Peters

2

一般情况下,您需要提供一个函数作为参数,当发生某些事情时调用该函数。

在C代码中,您将传递类似于以下内容的参数:

int (callback *)(void *, long );

意思是一个接收两个参数void *和long并返回int的函数。
在面向对象的语言中,语法有时更简单。例如,您可以构建一个回调机制,允许用户传递类似于函数或具有抽象方法(从而包装函数)和上下文数据的对象。
现代语言使用术语“委托”来指代函数“模式”。这些可用作回调函数。一些语言还使用术语lambda,它本质上是没有名称的函数,通常在代码块中“即时”创建并作为回调传递。C++11将其引入了标准中。
使用回调的好处是可以将API与调用它的内容分离,从某种程度上减少/解耦,反之亦然,即使在一个地方你知道你正在调用API,在“处理程序”的点上也不需要知道它是从哪里调用过来的。
例如,您可以拥有一个生成对象并在生成时“回调”的API。

1

回调意味着将代码作为参数传递。例如,想象一个按钮,当按下时显示对话框:

Button testBtn;
testBtn.setOnClickListener(new OnClickListener() {

  @Override
  public void onCLick() {
    JOptionPane.showDialog(testBtn, "Test button pressed");
  }
}

在这里,我们告诉按钮当它被点击时执行什么操作。因此,当框架检测到点击时,它将执行传递的代码。在框架内部有一些类似的代码:

void processEvent(Event e) {
  if (e.type == Event.CLICK) {
    e.getComponent().getOnClickListener().onClick();
  }
}

因此,一些基本的代码在适当的事件发生时回调监听器。

附注:这里是伪代码,只是为了描述这个想法。


0
回调方法是一种在事件发生时被调用的方法。

0
简单来说,回调其实就是一个函数或方法的引用,你可以将它作为参数传递给另一个函数,以便稍后回调它。

enter image description here

从上图可以看出,B_reference()是回调方法。 源代码示例:
>>> def A(A_msg,B_reference):
...  # After printing message, method B is called.
...  print(A_msg)
...  B_reference()
...

>>> def B():
...  print("Message from B")
...
>>>
>>> A("Message from A",B)
Message from A
Message from B
>>>

如果你还不明白这是什么意思,你可以查看这个视频


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