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

时间:2019-10-04 06:46:02

标签: function lambda delegates arguments d

如何使用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);
}

给我错误:

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

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


解决方案,借助答案,我将其固定为:

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(new Event());
    }
}

void main()
{
    auto variableFromParentScope = "lorem ipsum";
    auto target = new EventTarget();
    target.addEventListener(
        "load", 
        (Event event) {
            writeln(variableFromParentScope, event);
        }
    );
}

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

2 个答案:

答案 0 :(得分:4)

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

为进一步说明,我将向您展示如果将其扩展为较长的委托形式而不是使用速记=>

(Event event) => { writeln(variableFromParentScope, event); }

成为

(Event event) { return { writeln(variableFromParentScope, event); }; }

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

您的委托参数的替代有效格式为:

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

仅当您要返回内容时,才使用=>箭头。 () => { something }的用例是一个委托返回一个委托(例如,一个委托为给定的输入生成委托)

但是您的问题还存在一个错误,那就是您正在调用参数中使用, true来调用该函数,这使错误消息非常混乱,并且您没有将事件参数传递给回调,这将是代码段中的另一个错误。

答案 1 :(得分:2)

  

target.addEventListener("load", (Event event) => { writeln(variableFromParentScope, event); }, true);

(Args) => {}是一个lambda,它返回一个lambda。

更正表格:

  • target.addEventListener("load", (Event event) { writeln(variableFromParentScope, event); }, true);

  • target.addEventListener("load", (Event event) => writeln(variableFromParentScope, event), true);