Thread overview
Wanting an immutable associative array in a class
Jul 30, 2010
RedZone
Jul 30, 2010
bearophile
July 30, 2010
Hello,

I have a class wherein I want an immutable associative array.  I tried to do it like this:

class Foo
{
private:
     immutable int[char[]] Bar = ["AB":1, "CD":2, "EF":3];

public:
     this()
     {
          ...
     }

     ...
}

But the compiler tells me that ["AB":1, "CD":2, "EF":3] is not constant.

I've gotten around it by doing this, which works:

class Foo
{
private:
     immutable(int)[char[]] Bar;


     void initializeArray()
     {
           immutable(int)[char[]] FooBar = ["AB":1, "CD":2, "EF":3]
           Bar = FooBar;
     }
public:
     this()
     {
           initializeArray();
           ...
     }

     ...
}


But it would be nice if I could have the array reference itself be immutable and not just the array's contents.  Is there any way I could do this?
July 30, 2010
RedZone:
> But it would be nice if I could have the array reference itself be immutable and not just the array's contents.  Is there any way I could do this?

Let's say your code is as your second example:

class Foo {
    private:
        immutable int[string] bar;

    public:
        this() {
            bar = ["AB":1, "CD":2, "EF":3];
        }
}

void main() {
    auto f = new Foo;
}


How can you change the array reference outside the class constructor?

Bye,
bearophile
July 30, 2010
On Thu, 29 Jul 2010 22:55:35 -0400, bearophile wrote:

> RedZone:
>> But it would be nice if I could have the array reference itself be immutable and not just the array's contents.  Is there any way I could do this?
> 
> Let's say your code is as your second example:
> 
> class Foo {
>     private:
>         immutable int[string] bar;
> 
>     public:
>         this() {
>             bar = ["AB":1, "CD":2, "EF":3];
>         }
> }
> 
> void main() {
>     auto f = new Foo;
> }
> 
> 
> How can you change the array reference outside the class constructor?


But that was not his second example. :)  His second example used the type

  immutable(int)[char[]]

while you used the "correct" one,

  immutable(int[char[]])

RedZone:  Even though the overall type is immutable, you can still set it in a constructor, like bearophile showed.

May I also suggest a small improvement?  Doing it like this means that the array will be constructed anew every time you create an instance of the class.  If it's meant to be immutable, and you know all the elements of the array at compile time, that's just wasteful.  In that case, it's probably better to make it a static member variable, and set its value in a static constructor.  That way it will only get constructed once, at program startup.

  class Foo
  {
  private:
      static immutable int[string] bar;

      static this()  // Only run when program loads
      {
          bar = ["AB": 1, "CD": 2, "EF": 3];
      }

  public:
      ...
  }

-Lars