【发布时间】:2020-02-16 19:50:13
【问题描述】:
这是交易,
我正在编写一个 SDK,我想将观察者声明为协议,而不是类或结构(它有点像“观察者/委托”混合体)。
我希望能够比较作为协议引用传入的两个参数,而不是它们实际上是 IRL 的具体类/结构。
我知道进行比较的“简单”方法是将协议限制为Hashable 或Equatable,但我想避免给用户带来负担(这是一个 SDK)。
这是一个小操场,我的意思是:
protocol A {
func AFunc() -> String
}
class APrime: A {
func AFunc() -> String { "I AM GROOT" }
}
let variableA = APrime()
let variableB = APrime()
func compareTypes(_ inA: A, _ inB: A) -> String {
// if inA == inB {
// return ""
// }
return "not "
}
print("A is \(compareTypes(variableA, variableB))B.")
print("A is \(compareTypes(variableA, variableA))A.")
不修边幅的部分是compareTypes(_: A, _: A) 中的注释部分。我需要弄清楚如何在不进入“Hacksylvania”的情况下比较它们,我可以通过比较每个实例中 AFunc() 的地址来做到这一点。
预期的输出是:
A is not B.
A is A.
对于更“快速”的方法有什么想法吗?我一定是只见树木不见森林。
【问题讨论】:
-
假设 ClassA 和 ClassB 符合协议 A,并且您分别拥有这些类的
a和b实例。比较它们是否等于 qua 协议 A 可能意味着什么?除非您能保证a和b是同一类型,否则您甚至无法开始。 — 请注意,这正是 Swift 5.1some A解决的问题。如果您不想走那条路,则需要进行某种类型擦除,以便您比较的是 A-wrapper 类实例。 -
是的。这就是我正在看的。 “一些”很好,但我不确定它是否能解决问题。我正在寻找 identity 平等,而不是 type 平等。我有一种感觉,我最终不得不强制协议是平等的,但我想避免这种情况。
-
我认为您不太接受 what 是平等的。我要说的是 equatblity qua 协议的整个概念是不连贯的。协议不是一个东西。 协议采用者类型的实例是一个东西。您的标题“协议实例”的整个措辞似乎表明未能抓住这一点。没有“协议实例”之类的东西。
-
另一种可能是强制实现者提供一个 UUID 变量,该变量获取 SDK 分配的唯一 UUID。我以前做过。它很笨拙,但很有效。
-
“我正在寻找身份平等,而不是类型平等。”这就是
===,它只适用于类。 Structus 没有身份,因为它们在记忆中不断移动。结构的副本导致值的副本。类的副本会导致其引用的副本,但两个引用仍然指向堆中相同的唯一(就“身份”和内存位置而言)对象。