【问题标题】:Checking if two struct instances are different in Swift elegantly优雅地检查 Swift 中的两个结构实例是否不同
【发布时间】:2019-11-24 13:56:11
【问题描述】:

我为 Swift 制作了一个状态引擎,但有一些东西我想以显着的方式改进。

这是一个开源项目,你可以在这里查看:https://github.com/mrtksn/SwiftyState

我想改进的是处理状态变化的方式。

现在,状态变化是这样处理的:

let subscription = SwiftyState().subscribe { [weak self] in
    let state = $0 as! MyStore
    let oldState = $1 as? MyStore

    /// Your code goes here
}

您订阅状态更改,并且每当调用某个操作并完成更改状态时,都会调用订阅者并传递旧状态和新状态。 state 是一个结构体。

由于每次状态更改时都会运行它,因此用户需要检查状态更改是否与代码的那部分相关。如果看起来像这样:

let subscription = SwiftyState().subscribe { [weak self] in
    let state = $0 as! MyStore
    let oldState = $1 as? MyStore

if state.userName != oldState.userName {
     self?.nameLabel.text = state.userName
    }
}

我想要的是用更少的代码做到这一点,也许是这样的:

let subscription = SwiftyState().subscribe { [weak self] in
    let state = $0 as! MyStore
    let oldState = $1 as? MyStore

    /// Maybe assinging a closure to run when the state is changed
    state.userName.hasChanged = {
          self?.nameLabel.text = state.userName
    }

   /// Or maybe just tagging a property as changed 
   if state.userName.hasChanged {
      self?.nameLabel.text = state.userName
   }
   /// Or maybe having a list of changes in the state object
   if state.changes.contain("nameLabel") {
     self?.nameLabel.text = state.userName
   }
}

我考虑过创建一个扩展程序,但到目前为止我的成功有限。我有一些想法,但我遇到了一些导致结果不理想的问题。

也许 StackOverflow 的创造力或 Swift 方面的专业知识可以帮助我减少这里的样板代码?

有什么想法吗?

【问题讨论】:

    标签: swift functional-programming frameworks swift-extensions


    【解决方案1】:

    要比较 Swift 中的自定义类型,请将该类型符合 Equatable protocol 并实现其 public static func == (lhs: Self, rhs: Self) -> Bool 方法。

    这是一个示例,说明如何做到这一点。由于您没有添加MyStore 的定义,因此您也可以在那里实现相同的东西。

    struct MyStore: Equatable {
        var userName: String
    
        static func == (lhs: MyStruct, rhs: MyStruct) -> Bool {
            return lhs.userName == rhs.userName
        }
    }
    

    在上述方法中,添加您要比较MyStruct 实例的所有属性。目前,我只使用userName进行比较。

    比较 2 个structs 喜欢,

    let s1 = MyStruct(userName: "John")
    let s2 = MyStruct(userName: "Annie")
    if s1 == s2 {
        print("Equal")
    } else {
        print("Unequal")
    }
    

    同样适用于您的自定义类型是class

    【讨论】:

    • 当然,我们可以比较整个结构的结构,但我想进行结构属性比较,并以一种优雅的方式进行,减少代码,同时保留自动完成等 IDE 功能。检查我的例子。
    • 你为什么不干脆做oldState.userName == newState.userName
    • 这就是我目前所做的,但它看起来不太好,而且会变得非常拥挤,因为我需要输入两次属性名称。我想只绑一次就可以逃脱。我正在考虑为 Equatable 协议编写扩展,但我必须找到一种方法将其仅限于我的结构,并且还有其他复杂性,例如将旧状态存储在新状态中,通过 keyPath 访问属性等。
    猜你喜欢
    • 1970-01-01
    • 2017-10-04
    • 1970-01-01
    • 2019-12-27
    • 1970-01-01
    • 1970-01-01
    • 2018-04-30
    • 1970-01-01
    相关资源
    最近更新 更多