Is it possible in Swift to mutate an enum associated value, which is a value type? If yes, How?
struct S {
var a = 1
}
enum E {
case s(S)
}
var e = E.s(S())
// the goal is to make e hold s with a = 2
// overwriting e is not allowed
if case var .s(s) = e {
// s is a copy at this point
// I want to mutate e in-place
s.a = 2
}
NOTE: it seems to be possible, at least for the Optional enum s?.a = 2 mutates Optional<S>.
Use case:
I am writing a tiny wrapper around Codable, to easily map values between dictionaries and objects. I have a single MappingContext, which is either encode or decode. Given that KeyedEncodingContainer has a mutating function while encoding, and I would like the user of this wrapper to avoid reassigning the value, and just directly mutate the associated value.
I opened swift stdlib code, and the function doesn't even mutate the struct, yet is marked mutating. Not sure why, but I can have copies without issues now, but also reassigning is an acceptable solution, just wanted to make sure I am not missing anything obvious.
typealias EncodeContainer = KeyedEncodingContainer<JsonCodingKey>
typealias DecodeContainer = KeyedDecodingContainer<JsonCodingKey>
public enum CodingMode {
case encode(EncodeContainer)
case decode(DecodeContainer)
}
It's not possible to change an enum associated value, without overwriting the enum itself; if instead S is declared as class, it's a quite trivial task.
Anyway I did some experiments that I report here:
1) based on withUnsafeMutablePointer:
var e = E.s(S(a: 1))
withUnsafeMutablePointer(to: &e, {
$0.pointee = E.s(S(a: 2))
})
print(e)
2) declaring a mutating func for overwriting implicitly the enum
struct S {
var a = 1
}
enum E {
case s(S)
mutating func setS(val:S) { self = E.s(val) }
}
var e = E.s(S(a: 1))
e.setS(val: S(a: 2))
print(2)
3) if S is a class:
class S:CustomDebugStringConvertible {
var a = 1
var debugDescription: String { return "\(a)" }
}
enum E {
case s(S)
}
let e = E.s(S())
if case let .s(s) = e {
s.a = 2
}
print(e)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With