Thread overview |
---|
October 14, 2018 Help about Template and class inheritance | ||||
---|---|---|---|---|
| ||||
Here is a sample code ```d import std.stdio; class Future(T) { T result; this(T r) { this.result = r; } } interface IExecutorService { // Future!(T) submit(T)(T result); // can't be implemented } abstract class ExecutorService : IExecutorService { Future!(T) submit(T)(T result) { return new Future!(T)(result); } } class ThreadPoolExecutor : ExecutorService { // alias submit = ExecutorService.submit; // override Future!(T) submit(T)(T result) { // can't override it // return new Future!(T)(result + 10); // } } void main() { ThreadPoolExecutor service = new ThreadPoolExecutor(); ExecutorService serviceBase = service; IExecutorService serviceInterface = service; Future!(int) f = service.submit!int(12); writeln(f.result); f = serviceBase.submit!int(12); writeln(f.result); // f = serviceInterface.submit!int(12); // writeln(f.result); } ``` The **submit** can't be defined in D as done in Java. See also (search for exchangeMessageVectorsAsync): https://www.programcreek.com/java-api-examples/?code=aarmea/noise/noise-master/app/src/main/java/com/alternativeinfrastructures/noise/sync/StreamSync.java So, is there a better way to do this in D? Any suggestions are welcome. Thanks. |
October 14, 2018 Re: Help about Template and class inheritance | ||||
---|---|---|---|---|
| ||||
Posted in reply to Heromyth | On Sunday, 14 October 2018 at 13:21:00 UTC, Heromyth wrote:
> Here is a sample code
>
> ```d
> import std.stdio;
>
> class Future(T)
> {
> T result;
>
> this(T r) {
> this.result = r;
> }
> }
>
> interface IExecutorService {
> // Future!(T) submit(T)(T result); // can't be implemented
> }
>
> abstract class ExecutorService : IExecutorService {
> Future!(T) submit(T)(T result) {
> return new Future!(T)(result);
> }
> }
>
> class ThreadPoolExecutor : ExecutorService {
> // alias submit = ExecutorService.submit;
>
> // override Future!(T) submit(T)(T result) { // can't override it
> // return new Future!(T)(result + 10);
> // }
> }
>
> void main()
> {
> ThreadPoolExecutor service = new ThreadPoolExecutor();
> ExecutorService serviceBase = service;
> IExecutorService serviceInterface = service;
>
> Future!(int) f = service.submit!int(12);
> writeln(f.result);
>
> f = serviceBase.submit!int(12);
> writeln(f.result);
>
> // f = serviceInterface.submit!int(12);
> // writeln(f.result);
> }
>
> ```
>
> The **submit** can't be defined in D as done in Java. See also (search for exchangeMessageVectorsAsync):
>
> https://www.programcreek.com/java-api-examples/?code=aarmea/noise/noise-master/app/src/main/java/com/alternativeinfrastructures/noise/sync/StreamSync.java
>
> So, is there a better way to do this in D?
> Any suggestions are welcome.
> Thanks.
The basic problem you're faced to here is that D class / interface member functions that are templatized are never virtual. I'm not sure if i understand well the JAVA pattern you try to reproduce but since D interfaces can be templatized you can do something like this, using variadics:
import std.stdio;
class Future(T)
{
T result;
this(T r) {
this.result = r;
}
}
interface IExecutorService(Ts...) {
static foreach(T; Ts)
Future!T submit(T result);
}
abstract class ExecutorService(Ts...) : IExecutorService!Ts {
static foreach(T; Ts)
Future!T submit(T result) {
return new Future!(T)(result);
}
}
class ThreadPoolExecutor : ExecutorService!int {
override Future!int submit(int result) {
return new Future!int(result + 10);
}
}
void main()
{
ThreadPoolExecutor service = new ThreadPoolExecutor();
ExecutorService!int serviceBase = service;
IExecutorService!int serviceInterface = service;
Future!(int) f = service.submit(12);
writeln(f.result);
f = serviceBase.submit(12);
writeln(f.result);
f = serviceInterface.submit(12);
writeln(f.result);
}
so that you can submit and have Future for several types.
|
October 15, 2018 Re: Help about Template and class inheritance | ||||
---|---|---|---|---|
| ||||
Posted in reply to Basile B. | On Sunday, 14 October 2018 at 15:06:49 UTC, Basile B. wrote: > > The basic problem you're faced to here is that D class / interface member functions that are templatized are never virtual. I'm not sure if i understand well the JAVA pattern you try to reproduce but since D interfaces can be templatized you can do something like this, using variadics: > That's a good try. I want to have a try with template mixin. About Java's pattern, see also: https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ExecutorService.html The interface ExecutorService has many implements like AbstractExecutorService, ForkJoinPool, ScheduledThreadPoolExecutor, ThreadPoolExecutor etc. The sample above is updated: import std.stdio; class Future(T) { T result; this(T r) { this.result = r; } } interface IExecutorService { // Future!(T) submit(T)(T result); // can't be implemented } abstract class ExecutorService : IExecutorService { Future!(T) submit(T)(T result) { return new Future!(T)(result); } } class ThreadPoolExecutor : ExecutorService { // alias submit = ExecutorService.submit; // override Future!(T) submit(T)(T result) { // can't override it // return new Future!(T)(result + 10); // } } class ForkJoinPool : ExecutorService { // alias submit = ExecutorService.submit; // override Future!(T) submit(T)(T result) { // can't override it // return new Future!(T)(result * 10); // } } void testBase(ExecutorService service) { writeln("testBase: ", typeid(service)); Future!(int) f = service.submit!int(12); writeln(f.result); } void testInterface(IExecutorService service) { writeln("testInterface: ", typeid(service)); writeln("testInterface: ", typeid(cast(Object)service)); // Future!(int) f = service.submit!int(12); // writeln(f.result); } void main() { ThreadPoolExecutor threadPool = new ThreadPoolExecutor(); ForkJoinPool forkJoinPool = new ForkJoinPool(); testBase(threadPool); writeln(); testBase(forkJoinPool); writeln("\n"); testInterface(threadPool); writeln(); testInterface(forkJoinPool); } |
Copyright © 1999-2021 by the D Language Foundation