how much "real-life" code can be marked @safe ?
Paul Backus
snarwin at gmail.com
Sun Jul 4 13:19:25 UTC 2021
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;
}
```
More information about the Digitalmars-d-learn
mailing list