Thread overview | |||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
December 29, 2017 structs inheriting from and implementing interfaces | ||||
---|---|---|---|---|
| ||||
In C#, structs can inherit from and implement interfaces. ---- using System; interface IPrint { void Print(); } struct MyStruct : IPrint { public void Print() { Console.WriteLine(ToString()); } } public class Program { public static void Main() { MyStruct s = new MyStruct(); s.Print(); } } ---- https://dotnetfiddle.net/lpXR1O But in D it doesn't appear possible. ---- import std.stdio; interface IPrint { void print(); } // Error: base classes are not allowed for struct, did you mean ;? struct MyStruct : IPrint // Error: base classes are not allowed for struct, did you mean ;? { void print() { writeln("MyStruct"); } } void main() { MyStruct s; s.Print(); } ---- https://run.dlang.io/is/j4xwla Is that simply because it hasn't been implemented or suggested yet for D, or was there a deliberate design decision? Thanks for your insight, Mike |
December 29, 2017 Re: structs inheriting from and implementing interfaces | ||||
---|---|---|---|---|
| ||||
Posted in reply to Mike Franklin | On Friday, 29 December 2017 at 12:03:59 UTC, Mike Franklin wrote:
> In C#, structs can inherit from and implement interfaces.
>
> ----
> using System;
>
> interface IPrint
> {
> void Print();
> }
>
> struct MyStruct : IPrint
> {
> public void Print()
> {
> Console.WriteLine(ToString());
> }
> }
>
> public class Program
> {
> public static void Main()
> {
> MyStruct s = new MyStruct();
> s.Print();
> }
> }
> ----
> https://dotnetfiddle.net/lpXR1O
>
> But in D it doesn't appear possible.
> ----
> import std.stdio;
>
> interface IPrint
> {
> void print();
> }
>
> // Error: base classes are not allowed for struct, did you mean ;?
> struct MyStruct : IPrint // Error: base classes are not allowed for struct, did you mean ;?
> {
> void print()
> {
> writeln("MyStruct");
> }
> }
>
> void main()
> {
> MyStruct s;
> s.Print();
> }
> ----
> https://run.dlang.io/is/j4xwla
>
> Is that simply because it hasn't been implemented or suggested yet for D, or was there a deliberate design decision?
>
> Thanks for your insight,
>
> Mike
I think it simply hasn't been implemented, but I am not sure here because you could simply insert a `static assert` in there (and probably have something like `hasInterface!(Interface, YourStruct)`. Similarly multiple `alias this` is a request that often comes up.
|
December 29, 2017 Re: structs inheriting from and implementing interfaces | ||||
---|---|---|---|---|
| ||||
Posted in reply to Mike Franklin | Structs are structs, classes are classes. C++ had the mixed model similar to what you suggested, we got it right and kept it nice and separate. This was done on purpose. |
December 29, 2017 Re: structs inheriting from and implementing interfaces | ||||
---|---|---|---|---|
| ||||
Posted in reply to rikki cattermole | On Friday, 29 December 2017 at 12:11:46 UTC, rikki cattermole wrote: > Structs are structs, classes are classes. I'm talking about interfaces, which are neither structs nor classes. > C++ had the mixed model similar to what you suggested, we got it right and kept it nice and separate. This was done on purpose. I'm comparing with C#, not C++. And structs implementing interfaces does not blur the two concepts, as C# eloquently demonstrates. Mike |
December 29, 2017 Re: structs inheriting from and implementing interfaces | ||||
---|---|---|---|---|
| ||||
Posted in reply to Mike Franklin | On Friday, 29 December 2017 at 12:03:59 UTC, Mike Franklin wrote:
> In C#, structs can inherit from and implement interfaces.
>
> ----
> using System;
>
> interface IPrint
> {
> void Print();
> }
>
> struct MyStruct : IPrint
> {
> public void Print()
> {
> Console.WriteLine(ToString());
> }
> }
>
> public class Program
> {
> public static void Main()
> {
> MyStruct s = new MyStruct();
> s.Print();
> }
> }
> ----
> https://dotnetfiddle.net/lpXR1O
>
> But in D it doesn't appear possible.
> ----
> import std.stdio;
>
> interface IPrint
> {
> void print();
> }
>
> // Error: base classes are not allowed for struct, did you mean ;?
> struct MyStruct : IPrint // Error: base classes are not allowed for struct, did you mean ;?
> {
> void print()
> {
> writeln("MyStruct");
> }
> }
>
> void main()
> {
> MyStruct s;
> s.Print();
> }
> ----
> https://run.dlang.io/is/j4xwla
>
> Is that simply because it hasn't been implemented or suggested yet for D, or was there a deliberate design decision?
>
> Thanks for your insight,
>
> Mike
The problem is that interfaces are a runtime thing (e.g. you can cast a class to an interface)
structs implement compile time interfaces via template duck typing (usually enforced via an if()).
you could probably write a wrapper that introspected an interface and enforced that all members were implemented.
|
December 29, 2017 Re: structs inheriting from and implementing interfaces | ||||
---|---|---|---|---|
| ||||
Posted in reply to Mike Franklin | On Friday, 29 December 2017 at 12:03:59 UTC, Mike Franklin wrote: > Is that simply because it hasn't been implemented or suggested yet for D, or was there a deliberate design decision? It's a design decision. Look carefully at structs vs. classes here: https://dlang.org/spec/struct.html There is no virtual methods table (VMT) for structs, no inheritance. Structs have value semantics. A variable with a type of some interface implies it's a pointer, with reference semantics and a VMT. |
December 29, 2017 Re: structs inheriting from and implementing interfaces | ||||
---|---|---|---|---|
| ||||
Posted in reply to Mike Franklin | On Friday, December 29, 2017 12:18:57 Mike Franklin via Digitalmars-d-learn wrote:
> On Friday, 29 December 2017 at 12:11:46 UTC, rikki cattermole
>
> wrote:
> > Structs are structs, classes are classes.
>
> I'm talking about interfaces, which are neither structs nor classes.
Interfaces are related to classes and not structs. Structs do not have inheritance and do not implement interfaces in any way shape or form. Classes and interfaces are always references, whereas structs never are, and structs do not have virtual functions. Structs are either directly placed where they are (be it on the stack or inside an object that contains them), or they're placed on the heap and accessed via a pointer. As such, in D, structs are fundamentally different from classes or interfaces.
If you want a function to accept multiple types of structs or classes which share the same API, then use templates and use the template constraint to restrict what the template accepts. That's what's done with ranges (e.g. with isInputRange and isForwardRange).
- Jonathan M Davis
|
December 29, 2017 Re: structs inheriting from and implementing interfaces | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nicholas Wilson | On Fri, 29 Dec 2017 12:39:25 +0000, Nicholas Wilson wrote:
> On Friday, 29 December 2017 at 12:03:59 UTC, Mike Franklin wrote:
>
> The problem is that interfaces are a runtime thing (e.g. you can cast a
> class to an interface)
> structs implement compile time interfaces via template duck typing
> (usually enforced via an if()).
> you could probably write a wrapper that introspected an interface and
> enforced that all members were implemented.
I've actually thought about doing this to get rid of a bunch of if qualifiers in my function declarations. `static interface {}` compiles but doesn't [currently] seem to mean anything to the compiler, but could be a hint to the programmer that nothing will directly implement it; it's a compile-time interface. This would provide a more generic way of doing stuff like `isInputRange`, etc.
|
December 29, 2017 Re: structs inheriting from and implementing interfaces | ||||
---|---|---|---|---|
| ||||
Posted in reply to Mike Franklin | On Friday, 29 December 2017 at 12:03:59 UTC, Mike Franklin wrote: > In C#, structs can inherit from and implement interfaces. > > ---- > using System; > > interface IPrint > { > void Print(); > } > > struct MyStruct : IPrint > { > public void Print() > { > Console.WriteLine(ToString()); > } > } > > public class Program > { > public static void Main() > { > MyStruct s = new MyStruct(); > s.Print(); > } > } > ---- > https://dotnetfiddle.net/lpXR1O > > But in D it doesn't appear possible. > ---- > import std.stdio; > > interface IPrint > { > void print(); > } > > // Error: base classes are not allowed for struct, did you mean ;? > struct MyStruct : IPrint // Error: base classes are not allowed for struct, did you mean ;? > { > void print() > { > writeln("MyStruct"); > } > } > > void main() > { > MyStruct s; > s.Print(); > } > ---- > https://run.dlang.io/is/j4xwla > > Is that simply because it hasn't been implemented or suggested yet for D, or was there a deliberate design decision? > > Thanks for your insight, > > Mike This feature is criticized among the C# community: https://blogs.msdn.microsoft.com/abhinaba/2005/10/05/c-structs-and-interface/ no vtable means for example that you cannot back to something after extracting the interface (with classes you can always get back to Object) as in D, struct should really only be used for a custom type with value semantic. |
December 29, 2017 Re: structs inheriting from and implementing interfaces | ||||
---|---|---|---|---|
| ||||
Posted in reply to rjframe | On 29/12/2017 12:59 PM, rjframe wrote:
> On Fri, 29 Dec 2017 12:39:25 +0000, Nicholas Wilson wrote:
>
>> On Friday, 29 December 2017 at 12:03:59 UTC, Mike Franklin wrote:
>>
>> The problem is that interfaces are a runtime thing (e.g. you can cast a
>> class to an interface)
>> structs implement compile time interfaces via template duck typing
>> (usually enforced via an if()).
>> you could probably write a wrapper that introspected an interface and
>> enforced that all members were implemented.
>
> I've actually thought about doing this to get rid of a bunch of if
> qualifiers in my function declarations. `static interface {}` compiles but
> doesn't [currently] seem to mean anything to the compiler, but could be a
> hint to the programmer that nothing will directly implement it; it's a
> compile-time interface. This would provide a more generic way of doing
> stuff like `isInputRange`, etc.
Or we could get signatures, which are even better still!
|
Copyright © 1999-2021 by the D Language Foundation