Как я могу легко скопировать неизменяемую структуру в swift, изменяя только некоторые поля [Как метод копирования kotlin dataclass]? - PullRequest
0 голосов
/ 14 мая 2018

У меня есть быстрая структура, примерно такая:

struct LogicalState {
  let a: String?
  let b: Bool
  let c: Int
}

и изменчивый экземпляр этого состояния. Обратите внимание, что все свойства в этом состоянии 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, и я не уверен, какие еще варианты у меня есть?

Любое решение о том, как решить эту проблему, будет высоко ценится

1 Ответ

0 голосов
/ 14 мая 2018

Думаю, вы можете расширить структуру с помощью метода 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")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...