www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - mutable array of immutable objects

reply Jeff Thompson <nospam example.com> writes:
I want to create a mutable array of immutable objects, but the 
code below gives the error shown below. It seems that "new 
immutable(C)[1]" makes the entire array immutable, but it seems I 
should be able to change the elements of an array of pointers to 
an object even though the objects are immutable. How to do that?

class C {
   this(int x) immutable { this.x = x; }
   int x;
}

void main(string[] args)
{
   auto array = new immutable(C)[1];
   array[0] = new immutable C(10); // Error: Cannot modify 
immutable expression array[0].
}
Apr 19 2016
next sibling parent reply Anonymouse <asdf asdf.com> writes:
On Tuesday, 19 April 2016 at 10:41:05 UTC, Jeff Thompson wrote:
 I want to create a mutable array of immutable objects, but the 
 code below gives the error shown below. It seems that "new 
 immutable(C)[1]" makes the entire array immutable, but it seems 
 I should be able to change the elements of an array of pointers 
 to an object even though the objects are immutable. How to do 
 that?

 class C {
   this(int x) immutable { this.x = x; }
   int x;
 }

 void main(string[] args)
 {
   auto array = new immutable(C)[1];
   array[0] = new immutable C(10); // Error: Cannot modify 
 immutable expression array[0].
 }
Mind that this is akin to declaring a string (immutable(char)[]) and trying to modify an element. You can append, though. Or rather, make a new array/slice with the new elements concatenated into it.
Apr 19 2016
parent reply Jeff Thompson <nospam example.com> writes:
On Tuesday, 19 April 2016 at 11:43:22 UTC, Anonymouse wrote:
 On Tuesday, 19 April 2016 at 10:41:05 UTC, Jeff Thompson wrote:
 I want to create a mutable array of immutable objects, but the 
 code below gives the error shown below. It seems that "new 
 immutable(C)[1]" makes the entire array immutable, but it 
 seems I should be able to change the elements of an array of 
 pointers to an object even though the objects are immutable. 
 How to do that?

 class C {
   this(int x) immutable { this.x = x; }
   int x;
 }

 void main(string[] args)
 {
   auto array = new immutable(C)[1];
   array[0] = new immutable C(10); // Error: Cannot modify 
 immutable expression array[0].
 }
Mind that this is akin to declaring a string (immutable(char)[]) and trying to modify an element. You can append, though. Or rather, make a new array/slice with the new elements concatenated into it.
Thanks but then I'm confused as to why the following code is allowed. It is a mutable array of immutable strings. I can modify the array but not the elements they point to. What's so special about a string? Why can't I do that with my own class? void main(string[] args) { auto array = new string[1]; array[0] = "a"; }
Apr 19 2016
parent Timon Gehr <timon.gehr gmx.ch> writes:
On 19.04.2016 14:07, Jeff Thompson wrote:
 On Tuesday, 19 April 2016 at 11:43:22 UTC, Anonymouse wrote:
 On Tuesday, 19 April 2016 at 10:41:05 UTC, Jeff Thompson wrote:
 I want to create a mutable array of immutable objects, but the code
 below gives the error shown below. It seems that "new
 immutable(C)[1]" makes the entire array immutable, but it seems I
 should be able to change the elements of an array of pointers to an
 object even though the objects are immutable. How to do that?

 class C {
   this(int x) immutable { this.x = x; }
   int x;
 }

 void main(string[] args)
 {
   auto array = new immutable(C)[1];
   array[0] = new immutable C(10); // Error: Cannot modify immutable
 expression array[0].
 }
Mind that this is akin to declaring a string (immutable(char)[]) and trying to modify an element. You can append, though. Or rather, make a new array/slice with the new elements concatenated into it.
Thanks but then I'm confused as to why the following code is allowed. It is a mutable array of immutable strings.
mutable array of mutable strings, actually. immutable(string)[] would be a mutable array of immutable strings.
 I can modify the array but not
 the elements they point to. What's so special about a string?
string is not a class. It is an alias for immutable(char)[].
 Why can't I do that with my own class?
 ...
D has no built-in way to express it. There is https://dlang.org/phobos/std_typecons.html#.Rebindable.
Apr 19 2016
prev sibling parent =?UTF-8?Q?S=c3=b6nke_Ludwig?= <sludwig outerproduct.org> writes:
Am 19.04.2016 um 12:41 schrieb Jeff Thompson:
 I want to create a mutable array of immutable objects, but the code
 below gives the error shown below. It seems that "new immutable(C)[1]"
 makes the entire array immutable, but it seems I should be able to
 change the elements of an array of pointers to an object even though the
 objects are immutable. How to do that?

 class C {
    this(int x) immutable { this.x = x; }
    int x;
 }

 void main(string[] args)
 {
    auto array = new immutable(C)[1];
    array[0] = new immutable C(10); // Error: Cannot modify immutable
 expression array[0].
 }
Due to an omission in the type system, this requires the use of the helper type std.typecons.Rebindable: auto array = new Rebindable!(immutable(C))[1]; array[0] = new immutable C(10);
Apr 19 2016