Can't understand the application of delegates in toString() functions
Mathias Lang via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Mon Nov 7 08:37:50 PST 2016
On Monday, 7 November 2016 at 16:22:17 UTC, Heisenberg wrote:
> Hi there. I'm currently following Ali Çehreli's "Programming in
> D" book and I can't seem to be able to wrap my head around the
> of delegates in the toString() functions..
>
> http://ddili.org/ders/d.en/lambda.html
> (Bottom of the page)
>
>
> Why? How can a delegate which returns nothing be used as an
> array which is going to be printed on the screen? And just how
> is it printed? The Documentation didn't make it much clearer..
> the 'sink' is supposed to be the 'writer', isn't it? So what
> does it do? The arguments get interpreted and formatted into
> the string, but what happens after that?
>
> P.S. I've just checked the book, it doesn't seem to be
> explained anywhere properly (the way formattedRead is)
> P.P.S. I'm following the PDF version of the book
When you ask for a string (or more generally, an array), you put
a specific construct on the way the data should be. For starters,
the items have to be contiguous in memory. But most of the time,
they aren't, and you end up allocating memory to put them
contiguously.
A sink is a method to work around that problem. A simple example
would be:
```
import std.stdio;
void main ()
{
// A delegate that write to stdout
auto dg = (const(char)[] v) { write(v); }
ColoredPoint p;
p.toString(dg);
write("\n");
}
```
With this definition, every time `ColoredPoint` will want to
output a chunk of data, it will call the delegate, which will
print to stdout. When the function returns, we now all chunks
have been appended, and we complete the line with a \n, flushing
the output.
This is great to write memory-friendly algorithm:
```
void main ()
{
AppendBuffer!char myBuffer;
auto dg = (const(char)[] v) { myBuffer ~= v; }
ColoredPoint p;
p.toString(dg);
// Now we can use myBuffer.data
}
```
With this example, you can see that, by just forwarding chunks to
the delegate, we're able to let the caller to decide of the
memory strategy to use. It can be plain GC allocation, it can be
using `malloc` / `realloc`, it can use a static array and only
aggregate up to a certain size, etc...
More information about the Digitalmars-d-learn
mailing list