prathameshk
(Prathamesh Kowarkar)
1
I think it would be nice for Optional to have a subscript for a default value instead of relying on the nil coalescing operator, as follows:
extension Optional {
subscript(default defaultValue: @autoclosure () -> Wrapped) -> Wrapped {
get {
switch self {
case .none: return defaultValue()
case .some(let value): return value
}
}
set { self = newValue }
}
}
It can be used as follows:
let x: [Int?] = (0..<5).map { _ in Bool.random() ? 42 : nil }
print(x) // [Optional(42), nil, nil, Optional(42), Optional(42)]
print(x.map { $0[default: 0] }) // [42, 0, 0, 42, 42]
This behaviour matches Dictionary's subscript(_:default) functionality.
P.S.: This new subscript replicates Dictionary's existing default value subscript through currying, like so:
let dict = [1: "1", 2: "4", 3: "9", 4: "16"]
dict[-1][default: "0"] == dict[-1, default: "0"]
Looking forward to feedback on this. Thank you.
Edit: Made subscript settable.
1 Like
Nevin
2
Why do you prefer this over the more concise existing version?
print(x.map{ $0 ?? 0 })
2 Likes
prathameshk
(Prathamesh Kowarkar)
3
Suppose you have an object with a deeply nested optional variable:
struct Box {
var value: Int?
}
struct Package {
var box: Box
}
struct Container {
var package: Package
}
var container = Container(package: Package(box: Box(value: 2)))
And you have to mutate the value of the deeply nested optional, providing a default value if it is nil, you could extract the value to a local variable, mutate it and set the optional with the result. Like so:
var value = container.package.box.value
value = (value ?? 4) * 2
container.package.box.value = value
This unnecessarily creates a local variable and this can be avoided as follows:
container.package.box.value = (container.package.box.value ?? 4) * 2
Notice how the code is being duplicated on either side of the assignment.
Providing a subscript with a default value makes the code more succint and elegant to read, as follows:
container.package.box.value[default: 4] *= 2
Avoiding the issue of code duplication was the motivation behind Bool's toggle() and Dictionary's subscript(_:default:) methods and I propose Optional get the same upgrade.
7 Likes
jenox
(Christian Schnorr)
4
With a settable subscript this indeed looks like a nice addition. Personally I would like to see this change.
I'm not a fan of this, this makes Optional look like a Dictionary while it's something different entirely. The example you provided does make the code shorter but IMO it's not necessarily better in this case.
1 Like