D (dlang) 传递一个 lambda 函数作为参数

tir*_*hen 5 lambda delegates arguments d function

使用 D,如何将函数(可能是对函数的引用)作为要在其他函数中执行的参数传递?

import std.stdio : writeln;

class Event {}

class EventTarget
{
    void addEventListener(string eventName, void delegate(Event event) callback)
    {
        // TODO: add to slice to execute later, for now execute directly
        callback();
    }
}

void main()
{
    auto variableFromParentScope = "lorem ipsum";
    auto target = new EventTarget();
    target.addEventListener("load", (Event event) => { writeln(variableFromParentScope, event); }, true);
}
Run Code Online (Sandbox Code Playgroud)

给了我错误:

onlineapp.d(10): Error: delegate callback(Event event) is not callable using argument types ()
onlineapp.d(10):        missing argument for parameter #1: Event event
onlineapp.d(18): Error: function onlineapp.EventTarget.addEventListener(string eventName, void delegate(Event event) callback) is not callable using argument types (string, void delegate() @system delegate(Event event) pure nothrow @safe, bool)
onlineapp.d(18):        cannot pass argument __lambda1 of type void delegate() @system delegate(Event event) pure nothrow @safe to parameter void delegate(Event event) callback
Run Code Online (Sandbox Code Playgroud)

我在这里设置了示例:https : //run.dlang.io/is/FnQoId


解决方案,在答案的帮助下,我将其修复如下:

onlineapp.d(10): Error: delegate callback(Event event) is not callable using argument types ()
onlineapp.d(10):        missing argument for parameter #1: Event event
onlineapp.d(18): Error: function onlineapp.EventTarget.addEventListener(string eventName, void delegate(Event event) callback) is not callable using argument types (string, void delegate() @system delegate(Event event) pure nothrow @safe, bool)
onlineapp.d(18):        cannot pass argument __lambda1 of type void delegate() @system delegate(Event event) pure nothrow @safe to parameter void delegate(Event event) callback
Run Code Online (Sandbox Code Playgroud)

工作示例:https : //run.dlang.io/is/6aDRoU

Web*_*001 8

您对委托使用了错误的语法,因为您还可以在错误消息中看到它没有预期的类型。

为了进一步解释,我将向您展示如果将其扩展为更长的委托形式而不是使用简写形式,它会如何变化=>

(Event event) => { writeln(variableFromParentScope, event); }
Run Code Online (Sandbox Code Playgroud)

变成

(Event event) { return { writeln(variableFromParentScope, event); }; }
Run Code Online (Sandbox Code Playgroud)

如您所见,您正在返回一个在实际委托中没有参数的委托。如果您删除=>,您的委托将按预期工作。

您的委托参数的替代有效形式是:

(event) { ... }
delegate (Event event) { ... }
delegate (event) { ... }
&someMemberMethod // some object member method taking in Event as first parameter
toDelegate(&someGlobalFunction) // from std.functional
Run Code Online (Sandbox Code Playgroud)

只有当你想返回一些东西时,你才使用=>箭头。一个用例() => { something }是委托返回委托(例如委托为给定输入生成委托)

但你的问题也有错误,你, true在调用参数中使用 a 调用该函数,这使得错误消息非常混乱,并且你没有将事件参数传递给回调,这将是代码中的另一个错误片段。