Mix struct types in the same array
Paul Backus
snarwin at gmail.com
Thu Dec 19 21:26:51 UTC 2019
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
More information about the Digitalmars-d-learn
mailing list