On Thursday, 19 December 2019 at 18:21:32 UTC, tirithen wrote:
On Thursday, 19 December 2019 at 00:00:56 UTC, Paul Backus wrote:

interface Action
{
    void applyTo(ref User); <-- change to applyTo(T)(ref T)
}

class ActionAdapter(T) : Action
{
    T payload;

    this(T payload)
    {
        this.payload = payload;
    }

override void applyTo(ref User user) <-- change to applyTo(U)(ref U entity)
    {
        payload.applyTo(user);
    }
}

Is there a way I can make the example a bit more generic even by replacing the User type with a template. I tried:

applyTo(ref User); <-- applyTo(T)(ref T)
applyTo(ref User user) <-- applyTo(U)(ref U entity)

It compiled but crashed with:

Linking...
/usr/bin/ld: .dub/build/application-debug-linux.posix-x86_64-dmd_2089-4CFAD9B3CA5E5532C5E0608F9332C781/tryit.o: in function `_Dmain': .....tryit/source/app.d:55: undefined reference to `_D5plant5tryit3app5Event__T7applyToTSQBjQBgQBd4UserZQzMFKQvZv'
collect2: fel: ld returnerade avslutningsstatus 1

I'm still a bit new to this language so need to practice templates more, but I find D overall nice.

The reason this doesn't work is that interface methods are virtual, and virtual methods can't be templates. [1] If you want to have multiple kinds of entities, one option is to create an Entity interface and EntityAdapter(T) class using the same technique as above, and have your applyTo method accept an Entity as its argument. You can see an example of what that would look like at the following link:

https://gist.github.com/pbackus/f61734804a627d379c7916f783ea7725#file-oop_version-d

Another option is to forget about classes and interfaces and do everything with templates, using a library like sumtype [2]. Here's a link to an example of what that would look like:

https://gist.github.com/pbackus/f61734804a627d379c7916f783ea7725#file-template_version-d

Advantages of the interface + adapter version:
+ Can easily add new Actions and Entities, without changing existing code
  + Method dispatch is handled automatically by the compiler

Advantages of sumtype + templates version:
  + No need to allocate adapter objects on the heap

[1] https://dlang.org/spec/function.html#virtual-functions
[2] https://code.dlang.org/packages/sumtype

Reply via email to