# Ways to unwrap-mutate-wrap optionals

**URL:** <https://forums.swift.org/t/ways-to-unwrap-mutate-wrap-optionals/65934>\
**Category:** Discussion\
**Tags:** optional\
**Created:** [July 1, 2023, 7:21am UTC](https://forums.swift.org/t/ways-to-unwrap-mutate-wrap-optionals/65934 "2023-07-01T07:21:20Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![DanL](https://avatars.discourse-cdn.com/v4/letter/d/8baadc/32.png) [@DanL](https://forums.swift.org/u/DanL)\
**Post date:** [July 1, 2023, 7:21am UTC](https://forums.swift.org/t/ways-to-unwrap-mutate-wrap-optionals/65934/1 "2023-07-01T07:21:20Z")

</div>

Using `if let someOptional { }` is convenient, but it also  
means that the local unwrapped variable (or constant) makes  
the original optional, having the same name, inaccessible  
(a.k.a. variable shadowing).

Here are some possible solutions to unwrap-mutate-wrap  
optionals with `if let/var` without needing to come up with  
a new name for the unwrapped local variable.

Since the $ sign can be used in variable names, the following  
approach is currently possible. You still have to write the  
variable name twice, though.

```swift
var n: Int? = 1

if let n$ = n { n = n$ + 2 }

print(n) // 3

```

Three prospective solutions follow here below.

(1) I pitched this some time ago, where `pre` refers to a previous  
variable outside of the inner scope.

```swift
var n: Int? = 1

if let n { pre.n = n + 2 }

print(n) // 3

```

Mutating more than one optional is possible:

```swift
var n1: Int? = 1
var n2: Int? = 2

if let n1, let n2 { pre.n1 = n1 + 2; pre.n2 = n1 + n2 }

print(n1, n2) // both are 3

```

Note that `pre` could be used generally to access a variable with  
the same name, but being defined outside of the local scope:

```swift
let i: Int = 5

if condition {
    let i: Int = 2
    
    print(pre.i + i) // 7
}

```

(2) Use assignment from `if` statement. The rule would be that if  
there is only one statement between braces, the word `return`  
can be left out. If the optional is `nil`, no assignment takes place.

```swift
var n: Int? = 1

n = if let n { n + 2 }

print(n) // 3

```

If there is more than one statement between the braces, my  
suggestion would be to use the word `use` instead of `return`:

```swift
var n: Int? = 1

n = if let n { doChore(); use n + 2 }

print(n) // 3

```

(3) Differentiate (slightly less clear than the other solutions  
since it relies on assumptions).

Use `if let`, knowing that the optional is the one that it is  
possible to assign to.

```swift
var n: Int? = 1

if let n { n = n + 2 }

print(n) // 3

```

With `if var`, the local variable is the one that it is primarily  
possible to assign a new value to. Then, if the optional should  
be assigned to, do like this:

```swift
var n: Int? = 1

if var n { n += 2; n = n }

print(n) // 3

```

Other solutions are welcome.

---

<div class="post-metadata">

**Author:** ![vns](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/vns/32/37396_2.png) [@vns](https://forums.swift.org/u/vns)\
**Post date:** [July 1, 2023, 8:15am UTC](https://forums.swift.org/t/ways-to-unwrap-mutate-wrap-optionals/65934/2 "2023-07-01T08:15:59Z")

</div>

Just use map:

```swift
n = n.map { $0 + 2 }

```

---

<div class="post-metadata">

**Author:** ![vns](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/vns/32/37396_2.png) [@vns](https://forums.swift.org/u/vns)\
**Post date:** [July 1, 2023, 9:47am UTC](https://forums.swift.org/t/ways-to-unwrap-mutate-wrap-optionals/65934/4 "2023-07-01T09:47:04Z")

</div>

Didn't know about that syntax, that is better.

---

<div class="post-metadata">

**Author:** ![Zollerboy1](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/zollerboy1/32/12997_2.png) [@Zollerboy1](https://forums.swift.org/u/Zollerboy1)\
**Post date:** [July 1, 2023, 2:38pm UTC](https://forums.swift.org/t/ways-to-unwrap-mutate-wrap-optionals/65934/6 "2023-07-01T14:38:41Z")

</div>

> [@DanL](#):
>
> ```swift
> var n: Int? = 1
> 
> n = if let n { n + 2 }
> 
> print(n) // 3
> 
> ```

In Swift 5.9, this is almost possible like this:

```swift
var n: Int? = 1

n = if let n { n + 2 } else { nil }

print(n) // Actually prints 'Optional(3)'

```

---

<div class="post-metadata">

**Author:** ![DanL](https://avatars.discourse-cdn.com/v4/letter/d/8baadc/32.png) [@DanL](https://forums.swift.org/u/DanL)\
**Post date:** [July 2, 2023, 10:58am UTC](https://forums.swift.org/t/ways-to-unwrap-mutate-wrap-optionals/65934/7 "2023-07-02T10:58:57Z")

</div>

Great replies – much appreciated!

P.S. An alternative to the $ sign (that I introduced in my first example),  
could be to append \_u, where u stands for unwrapped.

```swift
var n: Int? = 1

if let n_u = n { n = n_u + 2 }

print(n) // 3

```

I don't know which one is better.
