swift - 如何在 swift 中轻松复制不可变结构,仅更改某些字段 [如 kotlin 数据类复制方法]?
问题描述
我有一个有点像这样的快速结构:
struct LogicalState {
let a: String?
let b: Bool
let c: Int
}
以及此状态的可变实例。注意状态中的属性都是 all let
,所以结构体本身是不可变的。
var _state: LogicalState
我想做的是强制执行允许更新状态的模式,但所有更新都必须是原子的 - 我不想简单地使 a、b 和 c 可变,因为这将允许 a 和 b 独立更改. 我需要控制更新并应用验证(例如,强制执行如果您更改a
,您也必须同时更改b
)
我可以通过简单地覆盖整个结构来做到这一点
_state = LogicalState(a: "newA", b: false, c: _state.c)
但是,如您所见,必须为不变的属性显式引用旧状态 ( _state.c
) 是烦人且有问题的,尤其是当您有更多属性时。我的真实示例有 10 个。
在 kotlin 中,它们具有公开“复制”方法的“数据类”,它允许您仅更改所需的参数。如果 swift 支持这样的事情,语法应该是这样的
func copy(a: String? = self.a, b:Bool = self.b, c:Int = self.c) ...
问题是,= self.a
swift 中不存在语法,我不确定我还有哪些其他选项?
任何有关如何解决此问题的解决方案将不胜感激
解决方案
想一想,您可以使用 copy(...) 方法扩展结构,将 nil 值作为默认值,并将它们替换为实例值,否则使用非 nil。例如这样的:
extension LogicalState {
func copy(a: String? = nil, b: Bool? = nil, c: Int? = nil) -> LogicalState {
return LogicalState(a: a ?? self.a, b: b ?? self.b, c: c ?? self.c)
}
}
因此,您可以在更改所需参数的同时使用它来复制实例:
let state = LogicalState(a: "A", b: false, c: 10)
let stateCopy1 = state.copy(c: 30)
let stateCopy2 = state.copy(a: "copy 2")
推荐阅读
- javascript - js switch 语句单元测试
- ms-access - O365 (Access 2016) 中的 VBA 拼写检查崩溃访问
- c# - 如何合并集合中的两个源并在组合框中正确显示它们?
- javascript - 带有动态 Jinja HTML 的动态 querySelector
- ios - 从数据中提取图像缩略图
- typescript - Typescript 中的枚举类型是什么?
- mysql - MySQL tc.log 文件
- python - 在python中将多维数组保存到图像
- recursion - 递归函数是如何在函数式语言中实现的?
- ruby-on-rails - 具有不同命名空间的模型/控制器的 Rails LoadError