Modifying the inside of Optional.some

I wonder if it's possible to modify some value of Optional without making a copy. The specific case where this comes up is conditionally creating a new value in Dictionary or appending to the current value.

This doesn't work because array gets copied:

switch dict[key] {
    case .none:
        dict[key] = [value]
    case .some(var array):

This works

if dict[key] == nil {
    dict[key] = [value]
} else {

However the working version has ! in it which reviewers have to spend time on checking if it can fail. One could use ? instead but then it'd silently stop appending if there's a mistake (during refactoring) and would be a nightmare to debug.

In other words, I wonder if it's possible to to directly translate this Rust code:

match map.get_mut(&key) {
    None => { map.insert(key, vec![value]); },
    Some(vec) => vec.push(value),

For this particular use case, you can use dictionary's default: subscript to provide the default value:

dict[key, default: []].append(value)

Thanks! Didn't notice this one in the docs.

To answer the broader question: yes, you can do this.

extension Optional {
    mutating func modify<ReturnType>(_ closure: (inout Wrapped) throws -> ReturnType) rethrows -> ReturnType? {
        if self == nil { return nil }
        return try closure(&self!)

As with some other questions around the use of _modify, the admittedly opaque incantation &self! is carrying a lot of load here. This convinces Swift to elide a copy into a temporary when it passes the inner value into the function argument. I'm honestly not 100% that this works in all edge cases, but so far this has worked in all situations where I've needed to use it.


As to other options with Dictionary specifically, there's also the answer I gave in this thread: Assigning a dictionary without re-hashing - #9 by lukasa