digitalmars.D.learn - Struct initializer in UDA
- realhet (8/8) Sep 26 2020 Hi,
- Anonymouse (5/13) Sep 26 2020 I don't think you can currently, no, but I'd be happy to be
- realhet (23/26) Sep 27 2020 All I can get is that the
- Anonymouse (29/56) Sep 27 2020 It works if you specialise opDispatch to take an int parameter
- realhet (17/21) Sep 27 2020 That looks the closes to the python named parameters or the
Hi, struct S{int a, b, c=9, d, e, f;} Is there a way or a trick to declare an UDA by using a nice struct initializer? It would be nice to be able to use the form: S{f:42} int a; //or something similar to this. instead of this longer and error-prone way: S(0, 0, 0, 9, 0, 42) int a;
Sep 26 2020
On Saturday, 26 September 2020 at 16:05:58 UTC, realhet wrote:Hi, struct S{int a, b, c=9, d, e, f;} Is there a way or a trick to declare an UDA by using a nice struct initializer? It would be nice to be able to use the form: S{f:42} int a; //or something similar to this. instead of this longer and error-prone way: S(0, 0, 0, 9, 0, 42) int a;I don't think you can currently, no, but I'd be happy to be proven wrong. The closest I can get is (S.init.c(9).f(42)) with use of opDispatch, which is easier to read but still ugly.
Sep 26 2020
On Saturday, 26 September 2020 at 17:13:17 UTC, Anonymouse wrote:On Saturday, 26 September 2020 at 16:05:58 UTC, realhet wrote: The closest I can get is (S.init.c(9).f(42)) with use of opDispatch, which is easier to read but still ugly.All I can get is that the - an identifier of a member is stronger than the opDispatch. -> Error: function expected before (), not S(0, 0).c of type int - and if I prefix it with '_' it ruins toString. -> Error: no property toString for type onlineapp.S import std.stdio, std.range, std.algorithm, std.traits, std.meta, std.conv, std.string, std.uni, std.meta, std.functional, std.exception; struct S{ int a, b; auto opDispatch(string name, T)(T value) if(name.startsWith("_")) { mixin(name[1..$], "= value;"); return this; } } void main(){ S.init._a(5).writeln; } Now I'm more confused, as the compiler completely ignores the if(name.startsWith("_")) constraint o.O
Sep 27 2020
On Sunday, 27 September 2020 at 10:17:39 UTC, realhet wrote:On Saturday, 26 September 2020 at 17:13:17 UTC, Anonymouse wrote:It works if you specialise opDispatch to take an int parameter instead of a type T. It smells like a bug but I don't know enough to say. I used two opDispatches to be able to avoid having to use _a and _b, and std.algorithm.comparison.among to constrain them. struct S{ private int _a, _b; auto opDispatch(string name)(int value) if (name.among("a", "b")) { mixin("_", name, "= value;"); return this; } auto opDispatch(string name)() if (name.among("a", "b")) { mixin("return _", name, ";"); } } void main(){ S.init.a(123).b(456).writeln; S().b(456).a(123).writeln; // Alternative syntax, may not work if opCall is defined } It's brittle in that you have to update and sync the two among("a", "b") constraints every time you add or remove a field, but I can't seem to get the names by introspection without it endlessly recursing over opDispatch again.On Saturday, 26 September 2020 at 16:05:58 UTC, realhet wrote: The closest I can get is (S.init.c(9).f(42)) with use of opDispatch, which is easier to read but still ugly.All I can get is that the - an identifier of a member is stronger than the opDispatch. -> Error: function expected before (), not S(0, 0).c of type int - and if I prefix it with '_' it ruins toString. -> Error: no property toString for type onlineapp.S import std.stdio, std.range, std.algorithm, std.traits, std.meta, std.conv, std.string, std.uni, std.meta, std.functional, std.exception; struct S{ int a, b; auto opDispatch(string name, T)(T value) if(name.startsWith("_")) { mixin(name[1..$], "= value;"); return this; } } void main(){ S.init._a(5).writeln; } Now I'm more confused, as the compiler completely ignores the if(name.startsWith("_")) constraint o.O
Sep 27 2020
On Sunday, 27 September 2020 at 11:59:49 UTC, Anonymouse wrote:On Sunday, 27 September 2020 at 10:17:39 UTC, realhet wrote:That looks the closes to the python named parameters or the struct initializer. For my use case this opDispatch trick seems to be more flexible than the named-parameters thing: (FieldProps().range(-360, 360).format("%.2f").caption("Turret rotation").unit("deg")) float alpha = 0; for example if I use the name: "logRange" it can also set the isLogarithmic flag as a side effect to true inside the FieldProps struct. Just by choosing a slightly different name. With this idealized format it would be not possible: FieldProps{ range: {-360, 360}, format:"%.2f", caption:"Turret rotation", unit:"deg"} float alpha = 0; The more work inside the struct is not a problem, because I'm willing to use it from 1000 places. Also __traits(allMembers) can help. Thank you!On Saturday, 26 September 2020 at 17:13:17 UTC, Anonymouse wrote:On Saturday, 26 September 2020 at 16:05:58 UTC, realhet wrote:
Sep 27 2020