Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/60.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Swift中比较两个协议实例的平等性_Swift_Protocols_Equatable - Fatal编程技术网

在Swift中比较两个协议实例的平等性

在Swift中比较两个协议实例的平等性,swift,protocols,equatable,Swift,Protocols,Equatable,事情是这样的 我正在编写一个SDK,我想将观察者声明为协议,而不是类或结构(它有点像“观察者/委托”的混合体) 我希望能够比较作为协议引用传入的两个参数,而不是它们实际上是的具体类/结构,IRL 我知道获得比较的“简单”方法是将协议限制为Hashable或equalable,但我希望避免给用户带来负担(这是一个SDK) 这里有一个小游乐场,我的意思是: protocol A { func AFunc() -> String } class APrime: A { func

事情是这样的

我正在编写一个SDK,我想将观察者声明为协议,而不是类或结构(它有点像“观察者/委托”的混合体)

我希望能够比较作为协议引用传入的两个参数,而不是它们实际上是的具体类/结构,IRL

我知道获得比较的“简单”方法是将协议限制为
Hashable
equalable
,但我希望避免给用户带来负担(这是一个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(\uA,\uA)
中注释掉的部分。我需要弄清楚如何在不进入“Hacksylvania”的情况下比较它们,我可以通过比较每个实例中AFunc()的地址来做到这一点

预期产出为:

A is not B.
A is A.

有没有更“快速”的方法?我一定是因为树木而错过了森林。

为了给这件事增加一些结尾,以下是我解决问题的方法:

protocol A {
    var uuid: Int { get } // This is the secret sauce. It will contain a unique UUID, associated with the instance.
    func AFunc() -> String
}

class APrime: A {
    let uuid: Int = Int.random(in: 0..<1000) // The UUID is initialized with the instance.
    func AFunc() -> String { "I AM GROOT" }
}

let variableA = APrime()
let variableB = APrime()
let variableC = variableA

func compareTypes(_ inA: A, _ inB: A) -> String {
    if inA.uuid == inB.uuid { // We compare UUIDs.
        return ""
    }
    return "not "
}

print("C is \(compareTypes(variableC, variableB))B.")

print("C is \(compareTypes(variableC, variableA))A.")
还有另一种方法(我有时也会用到):

哪些产出:

D is not E.
D is F.
G is not H.
G is I.
这允许以更编程的方式比较实例

如何不做

然后,当然,如果我们控制了实例,我们就可以真正做到平衡(这需要游乐场导入基础):

哪些产出:

D is not E.
D is F.
G is not H.
G is I.

假设ClassA和ClassB符合协议A,并且您分别拥有这些类的实例
A
b
。将它们作为协议A进行平等性比较可能意味着什么?你甚至不能开始,除非你能保证
a
b
是同一类型的请注意,这正是Swift 5.1
某些A
解决的问题。如果你不想走这条路,你需要进行某种类型的擦除,这样你比较的是A-wrapper类实例。是的。这就是我所看到的。“一些”很好,但我不确定它是否解决了问题。我在寻找身份平等,而不是类型平等。我有一种感觉,我最终将不得不强制协议是平等的,但我想避免这种情况。我不认为你完全接受什么是平等的。我想说的是,作为协议的平等性的整个概念是不连贯的。协议不是一回事。协议采用者类型的实例是一个问题。你的标题“协议实例”的整个措辞似乎表明你没有抓住这一点。没有所谓的“协议实例”,另一种可能是强制实现者提供一个UUID变量,该变量获取SDK分配的唯一UUID。我以前做过。这很难理解,但很有效。“我在寻找身份平等,而不是类型平等。”这就是
==
的含义,它只适用于类。Structus没有身份,因为它们在内存中不断移动。结构的副本导致值的副本。类的副本导致其引用的副本,但这两个引用仍然指向堆中相同的唯一(就“标识”和内存位置而言)对象。
G is not H.
G is I.