Problems with Array Assignment?

Adam D. Ruppe via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Wed May 10 13:01:16 PDT 2017


On Wednesday, 10 May 2017 at 17:26:09 UTC, Samwise wrote:
> I wondered about that when I did it, but I assumed (wrongly) 
> that since the name of the array was the same, it would 
> override it.

Nope, this is a somewhat common mistake coming from Python users, 
but it can't work that way in D since it would break static type 
guarantees - even if D did allow overriding variables, it would 
actually still flag your code as an error (try changing to a 
property getter, then you can override it, and you'll see it is 
an error).

So what happens here is the child class just adds a new variable. 
You can access them individually through 
`yourvar.ClassName.tiles` - parent and child accessible but 
separate. In the child class though, `this` automatically binds 
to the most-local variable.

A similar thing is this:

class Foo {
    int a;
    this(int a) {
       a = a; // will compile but does nothing
    }
}

Inside that constructor, `a` refers to the local parameter, not 
the class member. So you'd have to write `this.a = a;` to assign 
it.

(this is a FAQ too, so if you ever see a null that you could 
swear you initialized, this kind of mistake is usually the 
problem!)


But same deal with child class members. Local ones can have the 
same name but are separate.



Now, why would it be an error if it were allowed, like in the 
case of the property? It is because the base class can add ANY 
subclass of Tile, but the derived one assumes theya re all CTile:

Derived derived = new Derived();
Base base = derived; // allowed, now goes through base class 
interface

base.tiles ~= new OtherDerived(); // allowed, OtherDerived still 
comes from the same base class...

CTile = derived.tiles[0]; // uh oh, it is actually OtherDerived, 
not CTile!!!



In Python, since it is dynamically typed anyway, you don't have 
to worry about this as much, but in D since the base interface 
must still be usable, it would let you sidestep the child 
constraint entirely.





I'm probably not explaining this well, but you can read about the 
same principle from Java sources like this Wikipedia link:

https://en.wikipedia.org/wiki/Covariance_and_contravariance_(computer_science)#Arrays

D works the same way for the same reasons.

> Just to clarify, you can use a superclass variable to reference 
> a member of a subclass? That seems to be what's happening.

Only if it is a virtual method. What's really happening here is 
that superclass and subclass have their own tiles arrays so you 
override the function but not the member and the data gets split 
up.

tbh I kinda wish D would just call it an error to prevent the 
confusion.


More information about the Digitalmars-d-learn mailing list