Thread overview
Assoc. Array and struct with immutable member
Apr 15, 2018
Dgame
Apr 15, 2018
Alex
Apr 17, 2018
bauss
Apr 17, 2018
Alex
Apr 17, 2018
Jonathan M Davis
Apr 17, 2018
Dgame
April 15, 2018
How am I supposed to insert a struct with immutable members into an assoc. array?

Reduced example:
----
struct A {
    immutable string name;
}

A[string] as;
as["a"] = A("a"); // Does not work
----
April 15, 2018
On Sunday, 15 April 2018 at 17:59:01 UTC, Dgame wrote:
> How am I supposed to insert a struct with immutable members into an assoc. array?
>
> Reduced example:
> ----
> struct A {
>     immutable string name;
> }
>
> A[string] as;
> as["a"] = A("a"); // Does not work
> ----

Via a static this() it would work. But I guess, this is not what you are looking for, is it?

´´´
static this()
{
	as["a"] = A("a");
}

void main()
{	
	assert(as["a"].name == "a");
}


struct A {
    immutable string name;
}

A[string] as;
´´´


It also works, if you hide the AA in a class and all the insertions into the constructor.


´´´
/*
static this()
{
	as["a"] = A("a");
}
*/
void main()
{	
	auto c = new Container(A("a"));
	assert(c.as["a"].name == "a");
}

struct A {
    immutable string name;
}

class Container
{
	A[string] as;
	this(A a)
	{
		as[a.name] = a;
	}
}
´´´
April 17, 2018
On Sunday, 15 April 2018 at 18:51:52 UTC, Alex wrote:
> On Sunday, 15 April 2018 at 17:59:01 UTC, Dgame wrote:
>> How am I supposed to insert a struct with immutable members into an assoc. array?
>>
>> Reduced example:
>> ----
>> struct A {
>>     immutable string name;
>> }
>>
>> A[string] as;
>> as["a"] = A("a"); // Does not work
>> ----
>
> Via a static this() it would work. But I guess, this is not what you are looking for, is it?
>
> ´´´
> static this()
> {
> 	as["a"] = A("a");
> }
>
> void main()
> {	
> 	assert(as["a"].name == "a");
> }
>
>
> struct A {
>     immutable string name;
> }
>
> A[string] as;
> ´´´
>
>
> It also works, if you hide the AA in a class and all the insertions into the constructor.
>
>
> ´´´
> /*
> static this()
> {
> 	as["a"] = A("a");
> }
> */
> void main()
> {	
> 	auto c = new Container(A("a"));
> 	assert(c.as["a"].name == "a");
> }
>
> struct A {
>     immutable string name;
> }
>
> class Container
> {
> 	A[string] as;
> 	this(A a)
> 	{
> 		as[a.name] = a;
> 	}
> }
> ´´´

Even though it works in static this, then it still looks like a bug if you ask me, because the associative array itself isn't immutable.
April 17, 2018
On Sunday, April 15, 2018 17:59:01 Dgame via Digitalmars-d-learn wrote:
> How am I supposed to insert a struct with immutable members into an assoc. array?
>
> Reduced example:
> ----
> struct A {
>      immutable string name;
> }
>
> A[string] as;
> as["a"] = A("a"); // Does not work
> ----

I would point out that in general, having const or immutable fields in a struct is a terrible idea. It causes all kinds of problems because stuff like assignment doesn't work. If you want the field to be read-only, you'll have far fewer problems if you simply use a function to access it instead of making the member public. e.g.

struct A
{
public:

    @property string name() { return _name; }

private:

    string _name;
}

The problem you're having here is just one example of the list of things that don't work if you have a struct with immutable members. It looks like the AA probably is doing something like initializing the entry with A.init and then assigning it the new value, and that's not going to work if the struct has immutable members - which is exactly what the error message says.

- Jonathan M Davis

April 17, 2018
On Tuesday, 17 April 2018 at 11:07:55 UTC, bauss wrote:
>
> Even though it works in static this, then it still looks like a bug if you ask me, because the associative array itself isn't immutable.

Yeah... I'm not sure, if this behavior is wanted, too...

If you argue, that an absent field in in AA is not created, then it is a bug.
But if you argue that after creation of the AA everything is created, then adding another field is equal to modifying this very field, and that would be correctly forbidden.

So... no clue where a hint in the docu is hidden.
April 17, 2018
On Tuesday, 17 April 2018 at 11:38:17 UTC, Jonathan M Davis wrote:
> On Sunday, April 15, 2018 17:59:01 Dgame via Digitalmars-d-learn wrote:
>> How am I supposed to insert a struct with immutable members into an assoc. array?
>>
>> Reduced example:
>> ----
>> struct A {
>>      immutable string name;
>> }
>>
>> A[string] as;
>> as["a"] = A("a"); // Does not work
>> ----
>
> I would point out that in general, having const or immutable fields in a struct is a terrible idea. It causes all kinds of problems because stuff like assignment doesn't work. If you want the field to be read-only, you'll have far fewer problems if you simply use a function to access it instead of making the member public. e.g.
>
> struct A
> {
> public:
>
>     @property string name() { return _name; }
>
> private:
>
>     string _name;
> }
>
> The problem you're having here is just one example of the list of things that don't work if you have a struct with immutable members. It looks like the AA probably is doing something like initializing the entry with A.init and then assigning it the new value, and that's not going to work if the struct has immutable members - which is exactly what the error message says.
>
> - Jonathan M Davis

That's how I solved it. But it is troublesome and annoying because it increases the amount of manually work I have to do.