我发现代表的概念对我来说很难理解。我真的不明白为什么我不能简单地将一个函数传递给另一个函数,而需要将它包装到Delegate。我在文档中看到,有些情况下,我不知道它的名称,代表是唯一的方式来称呼它。
但现在我很难理解回调的概念。我试图找到更多的信息,但我无法理解的是,它只是调用其他函数或它是什么。
你能给出D回调的例子并解释它们在哪里有帮助吗?
import vibe.d;
shared static this()
{
auto settings = new HTTPServerSettings;
settings.port = 8080;
listenHTTP(settings, &handleRequest);
}
void handleRequest(HTTPServerRequest req,
HTTPServerResponse res)
{
if (req.path == "/")
res.writeBody("Hello, World!", "text/plain");
}&handleRequest是回调吗?它是怎样的工作,在什么时候开始?
发布于 2015-10-21 11:47:39
您可以将函数传递给以后调用的其他函数。
void test(){}
void receiver(void function() fn){
// call it like a normal function with 'fn()'
// or pass it around, save it, or ignore it
}
// main
receiver(&test); // 'test' will be available as 'fn' in 'receiver'您需要将函数名作为参数添加到&中,以澄清要传递函数指针。如果您不这样做,它将调用该函数,因为UFCS (调用时没有大括号)。它还不是代表。
接收您可调用的函数可以使用它做任何它想做的事情。一个常见的例子是在您的问题中,web服务回调。首先,告诉框架在收到请求时应该做什么(通过在函数中定义操作并使该函数对框架可用),在您的示例中,使用listenHTTP输入一个循环,当它收到请求时调用您的代码。如果您想阅读有关此主题的更多内容:处理程序
委托是带有上下文信息的函数指针。假设您希望添加对当前上下文中可用的其他元素进行操作的处理程序。就像把指示灯变成红色的按钮。示例:
class BuildGui {
Indicator indicator;
Button button;
this(){
... init
button.clickHandler({ // curly braces: implicit delegate in this case
indicator.color = "red"; // notice access of BuildGui member
});
button.clickHandler(&otherClickHandler); // methods of instances can be delegates too
}
void otherClickHandler(){
writeln("other click handler");
}
}在这个虚构的Button类中,所有单击处理程序都保存到列表中,并在单击列表时调用。
发布于 2015-10-21 07:34:17
因此,在内存中,函数只是一堆字节。就像数组一样,您可以获取指向它的指针。这是一个函数指针。它在D中有一种RETT function(ARGST)类型,其中RETT是返回类型,ARGST是参数类型。当然,属性可以像任何函数声明一样应用。
现在,委托是一个函数指针,是一个上下文指针。上下文指针可以是来自单个整数(参数)、调用框架(另一个函数中的函数)或最后一个类/结构的任何内容。
委托非常类似于RETT delegate(ARGST)中的函数指针类型。它们是不可互换的,但是您可以很容易地将函数指针转换为委托指针。
回调的概念是说,嘿,我知道你会知道X的,所以当这种情况发生时,请通过调用这个函数/委托来告诉我关于X的事情。
要回答你关于&handleRequest的问题,是的,这是一个回调。
发布于 2015-10-21 11:28:50
“行动纲领”中有几个问题。我将试着回答以下两个问题:
问:你能给出D回调的例子并解释它们在哪里有帮助吗?
A:它们通常用于支持委托的所有语言中(例如,C#)作为事件处理程序。-当事件被触发时,您给出一个要被调用的委托。不支持委托的语言为此使用类或回调函数。示例如何使用C++中使用FLTK2.0库:example2.html的回调。委托非常适合这一点,因为它们可以直接访问上下文。当您为此目的使用回调时,您必须传递在回调中要修改的所有对象.检查上面提到的FLTK链接作为示例--在那里,我们必须将指向fltk::Window对象的指针传递给window_callback函数,以便对其进行操作。( FLTK之所以这样做,是因为C++天生就没有lambdas,否则他们会使用它们而不是回调)
示例D使用:signals.html
Q:为什么我不能简单地将一个函数传递给另一个函数而需要将它包装到代表?
A:,您不必包装到委托-这取决于您想要完成什么.有时候,通过回调会对你起作用。您无法访问您可能想要调用回调的上下文,但委托可以。但是,您可以传递上下文(这就是一些C/C++库所做的)。
我认为你所要求的是在D语言参考资料中解释的
报价1:
函数指针可以指向静态嵌套函数。
报价2:
委托可以设置为非静态嵌套函数。
查看该部分中的最后一个示例,并注意委托如何成为一种方法:
struct Foo
{
int a = 7;
int bar() { return a; }
}
int foo(int delegate() dg)
{
return dg() + 1;
}
void test()
{
int x = 27;
int abc() { return x; }
Foo f;
int i;
i = foo(&abc); // i is set to 28
i = foo(&f.bar); // i is set to 8
}https://stackoverflow.com/questions/33252821
复制相似问题