Bug 8864 – Simpler syntax for array literal of structs from one argument
Status
RESOLVED
Resolution
WONTFIX
Severity
enhancement
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2012-10-21T14:25:30Z
Last change time
2018-01-27T21:08:47Z
Keywords
pull
Assigned to
No Owner
Creator
bearophile_hugs
Comments
Comment #0 by bearophile_hugs — 2012-10-21T14:25:30Z
I'd like to write code like this (the constructors of the structs must take 1 argument), because it's quite handy in many situations:
// some imports here
void main() {
BigInt[] data1 = [5, 6, 9];
Ranged!(int,5,10)[] data2 = [5, 6, 9];
Nibble[] data3 = [1, 2, 15]; // Nibble.sizeof == 1
alias Typedef!int Mint;
Mint[] data4 = [5, 6, 9];
}
Currently in D you write this, it's not handy if you have many items:
// some imports here
void main() {
auto data1 = [BigInt(5), BigInt(6), BigInt(9)];
alias Ranged!(int,5,10) R; // a short name
auto data2 = [R(5), R(6), R(9)];
auto data3 = [Nibble(1), Nibble(2), Nibble(15)];
alias Typedef!int Mint;
Mint[] data4 = [Mint(5), Mint(6), Mint(9)];
}
Or you duplicate the arrays:
import std.bigint;
void main() {
auto aux = [5, 6, 9];
auto data1 = new BigInt[aux.length];
foreach (i, a; aux)
data1[i] = BigInt(a);
// ...
}
A simpler example:
struct Nibble {
ubyte u;
this(ubyte ub)
in {
assert(ub < 16);
} body {
this.u = ub;
}
}
void main() {
Nibble[] data = [5, 6];
}
You currently write:
struct Nibble {
ubyte u;
this(ubyte ub)
in {
assert(ub < 16);
} body {
this.u = ub;
}
}
void main() {
auto data = [Nibble(5), Nibble(6)];
}
Scala accepts a similar syntax (Scala here probably uses a more general feature named implicits):
// Scala code
object Main extends App {
val data : Array[BigInt] = Array(10, 20, 30)
}
See also the discussion thread:
http://forum.dlang.org/thread/[email protected]
Comment #1 by bearophile_hugs — 2012-10-21T14:26:37Z
It's meant to work with 2D arrays too:
struct Nibble {
ubyte u;
this(ubyte ub)
in {
assert(ub < 16);
} body {
this.u = ub;
}
}
void main() {
Nibble[][] data = [[1, 2], [3, 4]];
}
Comment #2 by k.hara.pg — 2014-06-19T04:54:18Z
Today following style initializing is properly allwed:
struct S { this(int n) {} }
S s = 1; // translated to: T t = T(1);
As a natural conclusion, following syntax should also be accepted IMO.
S[] a = [1, 2, 3];
// For each ArrayInitializer elements, implicit struct
// constructor call of type S should be considered.
Then it could be translated to:
S[] a = [S(1), S(2), S(3)];
*** Issue 7255 has been marked as a duplicate of this issue. ***
Comment #5 by andrei — 2018-01-27T21:08:47Z
This is a core language change with many risks associated. A DIP would need to discuss them all.
Workarounds are possible with library code:
void main() {
BigInt[] data1 = makeArray!BigInt(5, 6, 9);
Ranged!(int,5,10)[] data2 = makeArray!(Ranged!(int,5,10))(5, 6, 9);
Nibble[] data3 = makeArray!Nibble[1, 2, 15]; // Nibble.sizeof == 1
alias Typedef!int Mint;
Mint[] data4 = makeArray!Mint(5, 6, 9);
}
Within the current language this is possible although not super handy:
BigInt[] data1 = only(5, 6, 9).map!(x => BigInt(x)).array;