是否可以在Swift中改变枚举关联值,这是一种值类型?如果是,怎么样?
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
}
注意:似乎有可能,至少Optional
枚举s?.a = 2
变异Optional<S>
。
用例:
我正在Codable
周围写一个小包装器,以便在字典和对象之间轻松映射值。我有一个MappingContext
,可以是encode
或decode
。鉴于KeyedEncodingContainer
在编码时具有变异功能,我希望此包装器的用户避免重新分配值,并直接改变相关值。
我打开了swift stdlib代码,该函数甚至没有改变结构,但标记为变异。不知道为什么,但我现在可以没有问题的副本,但重新分配是一个可接受的解决方案,只是想确保我没有遗漏任何明显的。
typealias EncodeContainer = KeyedEncodingContainer<JsonCodingKey>
typealias DecodeContainer = KeyedDecodingContainer<JsonCodingKey>
public enum CodingMode {
case encode(EncodeContainer)
case decode(DecodeContainer)
}
答案 0 :(得分:1)
在不覆盖枚举本身的情况下,无法更改枚举关联值;如果将S
声明为class
,那么这是一项非常简单的任务。
无论如何,我做了一些我在这里报告的实验:
var e = E.s(S(a: 1))
withUnsafeMutablePointer(to: &e, {
$0.pointee = E.s(S(a: 2))
})
print(e)
2)声明变异func
隐式覆盖枚举
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)如果S
是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)