With D, how can I pass a function (possibly reference to a function) as an argument to be executed inside other function?
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);
}
Gives me the error:
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
I have set up the example here: https://run.dlang.io/is/FnQoId
SOLUTION, With the help from the answers I fixed it like this:
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);
}
);
}
Working example: https://run.dlang.io/is/6aDRoU
You are using the wrong syntax for the delegate, as you can also see in the error message it doesn't have the expected type.
To explain further, I will show you how it changes if you extend it to the longer form of a delegate instead of using the shorthand =>
:
(Event event) => { writeln(variableFromParentScope, event); }
becomes
(Event event) { return { writeln(variableFromParentScope, event); }; }
As you can see you are returning a delegate with no parameters inside your actual delegate. If you remove the =>
, your delegate will work as expected.
Alternative valid forms for your delegate parameter would be:
(event) { ... }
delegate (Event event) { ... }
delegate (event) { ... }
&someMemberMethod // some object member method taking in Event as first parameter
toDelegate(&someGlobalFunction) // from std.functional
Only if you want to return something you use the =>
arrow. A use-case for () => { something }
would be a delegate returning a delegate (like a delegate generating delegates for a given input)
But also wrong in your question is that you are calling that function with a , true
in the calling parameters, which makes the error message very confused, and that you aren't passing an event parameter to the callback, which would be another error in the code snippet.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With