diff --git a/hands-on_dlang.md b/hands-on_dlang.md index 2cab56d..90ca607 100644 --- a/hands-on_dlang.md +++ b/hands-on_dlang.md @@ -67,6 +67,10 @@ - [Other templates](#other-templates) - [Template value parameters](#template-value-parameters) - [Other template parameters](#other-template-parameters) + - [Delegates](#delegates) + - [Functions as arguments](#functions-as-arguments) + - [Local functions with context](#local-functions-with-context) + - [Anonymous functions and lambdas](#anonymous-functions-and-lambdas) ## Setup @@ -1003,3 +1007,58 @@ void print(Args...)(Args args) { print(42, 3.5f, "foo"); print(); // also valid, prints nothing ``` + +### Delegates + +#### Functions as arguments + +Global functions can be referenced using the `function` type: + +```D +void doSomething(int function(int, int) doer) { + // call passed function + doer(5,5); +} + +auto add(int a, int b) { + return a + b; +} + +doSomething(&add); +``` + +#### Local functions with context + +To reference member functions or local functions, `delegate`s have to be used. You +can create _closures_ with this: + +```D +auto foo() { + int x = 42; + auto local() { + return x; + } + return &local; +} + +auto f = foo(); +static assert(is(typeof(f) == int delegate() pure nothrow @nogc @safe)); +writeln(f()); // 42 +``` + +#### Anonymous functions and lambdas +You can write anonymous functions and lambdas like this: + +```D +auto add = (int lhs, int rhs) { + return lhs + rhs; +}; + +auto lambdaAdd = (int lhs, int rhs) => lhs + rhs; +``` + +These are often passed as template arguments in the functional parts of Phobos: + +```D +[1, 2, 3].reduce!((a, b) => a + b)(); +```