On Sunday, 4 July 2021 at 08:43:11 UTC, Alexandru Ermicioi wrote:
On Saturday, 3 July 2021 at 20:09:56 UTC, tsbockman wrote:
On Saturday, 3 July 2021 at 16:06:33 UTC, Alexandru Ermicioi
wrote:
3. An edge case. Ex: You need to mutate some data and then
assume it is immutable in a constructor.
Can you give a valid example where that is necessary? The main
examples that I can think of either can be `@safe` with the
right API, or are motivated by a desire to avoid the GC and/or
druntime, thus falling under (1).
Can't remember any specific code now, but suppose you have a
mutable object as input to a function or constructor. You need
to return or assign an immutable copy of that struct and you
can do that with right copy constructor on that object, but
before that you need to do a couple of mutations on that
object. In this use case you can't avoid cast(immutable)
easily. Note: it is desired to not mutate the original object.
```d
immutable(Foo) example(ref Foo input)
{
Foo mutableCopy = input;
mutableCopy.mutate();
return immutable(Foo)(mutableCopy); // call copy ctor
}
```
I guess if your object is very expensive to copy you might want
to use `cast(immutable)` here, but IMO the real solution is to
refactor your code so that the call to `.mutate()` is not
necessary.
For example, let's say that what `mutate` does is change the
member variable `bar`. You could rewrite the above as:
```d
immutable(Foo) example(ref Foo input)
{
auto copy = immutable(Foo)(
// update this field
computeNewValue(input.bar),
// copy the rest
input.baz,
input.quux,
/* ... */
);
return copy;
}
```