Struct array assign?
bearophile
bearophileHUGS at lycos.com
Sat Jan 7 16:19:04 PST 2012
Currently D allows code like this (I think you are supposed to use opAssign here...):
struct MyTypedefInt {
int x;
this(int xx) { this.x = xx; }
// void opAssign(int xx) { this.x = xx; }
}
void main() {
MyTypedefInt x = 1; // OK
}
But if you put the elements into an array they are refused (the same problem happens with BigInts, etc):
struct MyTypedefInt {
int x;
this(int xx) { this.x = xx; }
// void opAssign(int xx) { this.x = xx; }
}
void main() {
MyTypedefInt[2] a3 = [1, 2]; // Error: cannot implicitly convert expression
}
This too is not accepted:
struct MyTypedefInt {
int x;
this(int xx) { this.x = xx; }
// void opAssign(int xx) { this.x = xx; }
}
void main() {
MyTypedefInt[2] a3 = [{ 1 }, { 2 }];
}
test.d(7): Error: struct MyTypedefInt has constructors, cannot use { initializers }, use MyTypedefInt( initializers ) instead
test.d(7): Error: struct MyTypedefInt has constructors, cannot use { initializers }, use MyTypedefInt( initializers ) instead
This is accepted:
struct MyTypedefInt {
int x;
this(int xx) { this.x = xx; }
}
void main() {
MyTypedefInt[2] a3 = [MyTypedefInt(1), MyTypedefInt(2)];
}
but it's not so nice to write, even if you shorten the name of MyTypedefInt to a single char:
struct MyTypedefInt {
int x;
this(int xx) { this.x = xx; }
}
void main() {
alias MyTypedefInt M;
MyTypedefInt[2] a3 = [M(1), M(2)];
}
So is it possible and wise to support code like:
MyTypedefInt[2] a3 = [1, 2];
MyTypedefInt[] a4 = [1, 2];
MyTypedefInt[][] a5 = [[1, 2], [3, 4]];
Here is an usage example of code like that, this is Ada code:
subtype Number is Natural range 0 .. 9;
subtype Valid_Number is Number range 1 .. 9;
type Board is array (Valid_Number, Valid_Number) of Number;
Sample_Board : Board := (1 => (3, 9, 4, 0, 0, 2, 6, 7, 0),
2 => (0, 0, 0, 3, 0, 0, 4, 0, 0),
3 => (5, 0, 0, 6, 9, 0, 0, 2, 0),
4 => (0, 4, 5, 0, 0, 0, 9, 0, 0),
5 => (6, 0, 0, 0, 0, 0, 0, 0, 7),
6 => (0, 0, 7, 0, 0, 0, 5, 8, 0),
7 => (0, 1, 0, 0, 6, 7, 0, 0, 8),
8 => (0, 0, 9, 0, 0, 8, 0, 0, 0),
9 => (0, 2, 6, 4, 0, 0, 7, 3, 5));
With the change I have suggested (plus library-defined TypeDef and SubRange) you are able to write something similar in D2 too (here I have ignored Valid_Number, the type of the array index), despite it looks a bit worse:
alias TypeDef!(SubRange!(size_t, 0, 10)) Number;
alias TypeDef!(Number[9][9]) Board;
Board sampleBoard = [[3, 9, 4, 0, 0, 2, 6, 7, 0],
[0, 0, 0, 3, 0, 0, 4, 0, 0],
[5, 0, 0, 6, 9, 0, 0, 2, 0],
[0, 4, 5, 0, 0, 0, 9, 0, 0],
[6, 0, 0, 0, 0, 0, 0, 0, 7],
[0, 0, 7, 0, 0, 0, 5, 8, 0],
[0, 1, 0, 0, 6, 7, 0, 0, 8],
[0, 0, 9, 0, 0, 8, 0, 0, 0],
[0, 2, 6, 4, 0, 0, 7, 3, 5]];
This *encourages* to write D code with more static safety, that for me is one of the main purposes of using static typing in the first place. D is designed to write more than just game engines :-)
Bye,
bearophile
More information about the Digitalmars-d
mailing list