Simple immutable example doesn't work - why???
Kenji Hara
k.hara.pg at gmail.com
Tue Nov 12 00:06:43 PST 2013
On Tuesday, 12 November 2013 at 01:15:02 UTC, Louis Berube wrote:
> Thanks, I think I understand. Now, how about an array of
> immutables:
>
> immutable class Test
> {
> public:
> this(in uint value)
> {
> this.value = value;
> }
> unittest
> {
> auto t = new immutable Test(4);
> assert (t.value == 4);
> }
> unittest
> {
> auto tarray = new immutable(Test)[3];
> tarray[0] = new immutable Test(4);
> // "Error: cannot modify
> // immutable expression
> // tarray[0]"
> }
> private:
> uint value;
> }
>
> I thought the parantheses in the array declaration would do the
> trick, but apparently not.
Once you initialize an immutable class reference, you won't be
able to rebind it anymore.
As far as I know there's two straight methods.
immutable class Test
{
this(in uint value)
{
this.value = value;
}
uint value;
}
void main()
{
version(Try1)
{
// 1. concatenate elements
immutable(Test)[] tarray;
tarray ~= new immutable Test(2);
tarray = new immutable Test(1) ~ tarray;
}
else
{
// 2. use array literal syntax
auto tarray = [
new immutable Test(1),
new immutable Test(2),
];
}
static assert(is(typeof(tarray[0]) == immutable(Test)));
assert(tarray.length == 2)
assert(tarray[0].value == 1);
assert(tarray[1].value == 2);
}
In D, you can reserve continuous memory area for array appending
by using built-in 'reserve' method. Therefore in most cases,
"reserve elements on empty array, then append created elements"
would be the efficient way to initialize the array of immutable
elements.
void main()
{
immutable(Test)[] tarray;
tarray.reserve(2);
auto save_ptr = tarray.ptr;
assert(save_ptr !is null && tarray.capacity >= 2);
// underlying memory is allocated and the appendable number
is more than 2.
assert(tarray.length == 0);
// but array itself is still empty.
tarray ~= new immutable Test(1);
tarray ~= new immutable Test(2);
assert(tarray.length == 2);
// array is expectedly filled.
assert(tarray.ptr is save_ptr);
// But the two concatenations didn't reallocate underlying
memory.
}
And I don't recommend to use std.exception.assumeUnique, because
it is just a cosmetic function to make ugly (but necessary for
some reason) array cast grep-able and human-readable.
Kenji Hara
More information about the Digitalmars-d-learn
mailing list