How to make Rust trait like feature in dlang ?

Mike Franklin slavo5150 at yahoo.com
Mon Jun 17 13:17:40 UTC 2019


On Monday, 17 June 2019 at 12:11:19 UTC, lili wrote:

> Yes, It's ok. but this did not represent to an conception under 
> code.
> I want to explicitly represent this is a SocketLike cenception.
> because i want conception oriented programming not type 
> oriented, this is more powerful in GP.

It can still be done in D.  It's just the `std.traits` module is 
missing the `implements` trait I've naively implemented below:

```
import std.stdio;
import std.traits;

template implements(T, I)
{
     static foreach(m; __traits(allMembers, I))
     {
         static assert(
             is(typeof(__traits(getMember, T, m)) == 
typeof(__traits(getMember, I, m))),
             "`" ~ T.stringof ~ "` does not implement `" ~ 
I.stringof ~ "."
             ~__traits(identifier, __traits(getMember, I, m)) ~ 
"`");
     }
     enum implements = true;
}

interface ISocket
{
     int send(ubyte[] data, int len);
     int recv(ubyte[] buff, int len);
}

struct TcpSocket
{
     int send(ubyte[] data, int len) { writeln("TcpSocket send"); 
return len; }
     int recv(ubyte[] buff, int len) { writeln("TcpSocket recv"); 
return len; }
}

struct UdpSocket
{
     int send(ubyte[] data, int len) { writeln("UdpSocket send"); 
return len; }
     int recv(ubyte[] buff, int len) { writeln("UdpSocket recv"); 
return len; }
}

struct UnixSocket
{
     int send(ubyte[] data, int len) { writeln("UnixSocket send"); 
return len; }
     int recv(ubyte[] buff, int len) { writeln("UnixSocket recv"); 
return len; }
}

struct NotASocket { }

void Use(T)(T socket)
     if (implements!(T, ISocket)) // ensures `T : ISocket`
{
     socket.send([], 0);
     socket.recv([], 0);
}

void main()
{
     TcpSocket socket;
     socket.Use();

     NotASocket noSocket;
     noSocket.Use(); // Error: static assert:  "NotASocket does 
not implement ISocket.send"
}
```
https://run.dlang.io/is/KZcp1S

There's probably a much more professional and elegant way to 
write `implements`, but you get the idea.  It would probably be a 
worthwhile addition to the `std.traits` module for those that 
prefer it.

Mike


More information about the Digitalmars-d mailing list