- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我这里有一个小型聊天应用程序。
我可以有两种类型的消息: - 文本 - 视频
我在解码 JSON 时使用多态性,如下所示:
import Foundation
enum MessageType: Int, Decodable {
case text
case video
}
protocol Message: Decodable {
static var type: MessageType { get }
var id: String { get }
var user: User { get}
var timestamp: String { get }
}
struct TextMessage: Message {
static var type: MessageType = .text
var id: String
var user: User
var timestamp: String
let text: String
}
struct VideoMessage: Message {
static var type: MessageType = .video
var id: String
var user: User
var timestamp: String
let text: String
let link: String
let poster: String
}
enum MessageWrapper: Decodable {
enum CodingKeys: String, CodingKey {
case type
}
case text(TextMessage)
case video(VideoMessage)
var item: Message {
switch self {
case .text(let item): return item
case .video(let item): return item
}
}
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
let type = try values.decode(Int.self, forKey: .type)
switch type {
case MessageType.text.rawValue: self = .text(try TextMessage(from: decoder))
case MessageType.video.rawValue: self = .video(try VideoMessage(from: decoder))
default:
throw DecodingError.dataCorruptedError(forKey: .type,
in: values,
debugDescription: "Invalid type")
}
}
}
我也在使用 MVVM 方法,如下所示:
struct ChatViewModel {
enum ViewModelType {
case loading
case text(TextMessageViewModel)
case video(VideoMessageViewModel)
case failure(ErrorViewModel)
}
enum State {
case initialized
case loading
case loaded([Message])
case failed(Error)
}
let state: State
let viewModels: [ViewModelType]
init(with state: State) {
self.state = state
switch state {
case .initialized:
viewModels = []
case .loading:
viewModels = [
.loading,
]
......
}
}
为了能够使用 Diffing
库,如 Differ ,ChatViewModel
应符合 Equatable
协议(protocol)。
extension ChatViewModel: Equatable {
static func == (lhs: ChatViewModel, rhs: ChatViewModel) -> Bool {
return lhs.state == rhs.state
}
}
extension ChatViewModel.State: Equatable {
static func == (lhs: ChatViewModel.State, rhs: ChatViewModel.State) -> Bool {
switch (lhs, rhs) {
case (.initialized, .initialized): return true
case (.loading, .loading): return true
case let (.loaded(l), .loaded(r)): return l == r
case let (.failed(l), .failed(r)): return l.localizedDescription == r.localizedDescription
default: return false
}
}
}
这里的问题是 case let (.loaded(l), .loaded(r)): return l == r
, Message
作为协议(protocol),不符合Equatable
。
使其符合Equatable
,例如
protocol Message: Decodable, Equatable {
static var type: MessageType { get }
var id: String { get }
var user: User { get}
var timestamp: String { get }
}
产生错误协议(protocol)“Message”只能用作通用约束,因为它对
:MessageWrapper
有 Self 或关联类型要求
enum MessageWrapper: Decodable {
...
var item: Message { // Protocol 'Message' can only be used as a generic constraint because it has Self or associated type requirements
switch self {
case .text(let item): return item
case .video(let item): return item
}
}
...
}
有什么想法或建议可以有一个干净的方法来解决这个问题吗?我看到了一些关于类型删除
的帖子,但经过一些测试后,我不确定它是否真正解决了问题。
最佳答案
您不必遵守 Equatable
即可使用 ==
运算符。您可以自己定义一个这样的运算符,而无需遵守 Equatable
。
为了方便起见,我假设 TextMessage
和 VideoMessage
已经符合 Equatable
。
首先,编写一个比较 Message
的方法:
func messageEqual(m1: Message, m2: Message) -> Bool {
if let textMessage1 = m1 as? TextMessage, let textMessage2 = m2 as? TextMessage {
return textMessage1 == textMessage2
}
if let videoMessage1 = m1 as? VideoMessage, let videoMessage2 = m2 as? VideoMessage {
return videoMessage1 == videoMessage2
}
return false
}
然后是 [Message]
的 ==
运算符:
func ==(messages1: [Message], messages2: [Message]) -> Bool {
return messages1.count == messages2.count &&
zip(messages1, messages2).allSatisfy(messageEqual)
}
现在 l == r
应该可以编译了。
关于ios - 符合 Equatable for Diffing 的协议(protocol),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58580011/
嗨,我是 Flutter 的新手,我正在尝试了解 block 计时器 In the doc of flutter_bloc我会知道这个构造函数类是什么意思 @immutable abstract cl
更新: 从包含 Swift 4.1 的 Xcode 9.3 开始,数组相等性按预期工作,原始问题中的代码编译没有错误。 但是,请查看已接受的答案,因为它提供了更好、更现代的解决方案。 原题如下: 当我
我收到了一个 100 页的 Latex 文档,其中包含 $$...$$ 之间的所有方程,我需要将它们全部更改为 \begin{equation}...\end{equation} 在 Latex(一些
I have 5 equations and I've to take combination of 3 equations at a time to check if I'm getting
关闭。这个问题是off-topic .它目前不接受答案。 想改善这个问题吗? Update the question所以它是 on-topic对于堆栈溢出。 10年前关闭。 Improve this
我想在 Modelica 中建模一个显式时间相关的微分方程。 说我想建模 Real x(start=1); der(x) = t; 在 Modelica 中。访问时间变量 t 的正确方法是什么? 最佳
我在 Maxima 中有一个微分方程组。我正在尝试绘制解决方案。 diff_eq1: 'diff(p(t),t) = (5/2 + (3^(1/2))/24 - (5/8)*p(t) - ((3^(1
基本上我只想解决k。请注意,等式等于 1.12 import math from sympy import * a = 1.45 b = 4.1 c = 14.0 al = math.log(a, 2
计算日出/日落时如何考虑观察者海拔? 计算任何纬度/经度的日出/设置是没有问题的,但是如何计算海拔而不是海平面???我已经用完了可以尝试的组合,并且花了三天多的时间来寻求帮助 我正在使用 Paul S
有人能给我一个为什么这不起作用的充分理由吗: let a: [Int]? = [1] let b: [Int]? = nil a == b 这将是我提出的(如果不优雅的话)解决方案。但这是微不足道的,
我正在尝试定义一个符合 Equatable 的测试夹具,以便我可以验证采用协议(protocol)的函数是否按预期执行。我尝试了 3 种不同的排列方式。 import XCTest import My
我确实需要将任何等同的结构/类型/对象传递给此 setEquatable 函数。知道如何解决这个问题吗? public func ==(l: [String: String], r: [String:
这个有效: // Conformance to protocol correctly synthesized by compiler struct MyStruct: Equatable { } 这不
我仍在与 Swift 泛型作斗争。今天我发现如果从泛型类调用我的 Equatable 协议(protocol)实现不起作用。 我的模型类: func ==(lhs: Tracking, rhs: Tr
谁能给我一个很好的理由来说明为什么这不起作用: let a: [Int]? = [1] let b: [Int]? = nil a == b 这将是我提出的(如果不雅)解决方案。但这是微不足道的,所以
题目地址:https://leetcode.com/problems/solve-the-equation/description/ 题目描述: Solve a given equation an
我正在尝试像这样解决这个指数方程: my ($l,$r); for (1 .. 100) -> $x { $l = $x * e ** $x; $r = 5 * (e ** $x -
我正在尝试用这段代码求解方程: a = [-0.0008333 -0.025 -0.6667 -20]; length_OnePart = 7.3248; xi = -6.4446; yi = -16
我正在处理一个说要使用这个 16 位循环冗余校验的设备: CCITT CRC-16 with polynomial x^16 + x^12 + x^5 + x^1 我寻找了这种算法的实现,但我确实只找
我在 hackerrank.com 上的“方程”挑战赛的一些测试用例上遇到了问题。这是问题所在:https://www.hackerrank.com/challenges/equations . 我很
我是一名优秀的程序员,十分优秀!