digitalmars.D - Struct array assign?
- bearophile (78/78) Jan 07 2012 Currently D allows code like this (I think you are supposed to use opAss...
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
Jan 07 2012