Swift 在两个协议对象上使用equals

Swift 在两个协议对象上使用equals,swift,operator-overloading,protocols,equatable,Swift,Operator Overloading,Protocols,Equatable,理想情况下,我会让服务器实现equalable协议,但我遇到了问题。这是我的密码 protocol Server { var ipAddress: String { get } // simplified for this question } func ==<T:Server>(lhs: T, rhs: T) -> Bool { return lhs.ipAddress == rhs.ipAddress } func !=<T:Server&

理想情况下,我会让服务器实现equalable协议,但我遇到了问题。这是我的密码

protocol Server {
    var ipAddress: String { get }
    // simplified for this question
}

func ==<T:Server>(lhs: T, rhs: T) -> Bool {
    return lhs.ipAddress == rhs.ipAddress
}

func !=<T:Server>(lhs: T, rhs: T) -> Bool {
    return lhs.ipAddress != rhs.ipAddress
}

func ==<T:Server, U:Server>(lhs: T, rhs: U) -> Bool {
    return lhs.ipAddress == rhs.ipAddress
}

func !=<T:Server, U:Server>(lhs: T, rhs: U) -> Bool {
    return lhs.ipAddress != rhs.ipAddress
}

func doSomething(server0: Server, server1: Server) {
    // I want to compare to Server objects

    // !!! Compile Error !!!
    // Binary operator '==' cannot be applied to two 'Server' operands
    guard server0 == server1 else {
        print("SAME BAD")
        return
    }

    print("DO stuff")
}
协议服务器{
var-ipAddress:字符串{get}
//简化了这个问题
}
func==(左:T,右:T)->Bool{
返回lhs.ipAddress==rhs.ipAddress
}
func=(左:T,右:T)->布尔{
返回lhs.ipAddress!=rhs.ipAddress
}
func==(左:T,右:U)->Bool{
返回lhs.ipAddress==rhs.ipAddress
}
func=(左:T,右:U)->布尔{
返回lhs.ipAddress!=rhs.ipAddress
}
func doSomething(服务器0:Server,服务器1:Server){
//我想与服务器对象进行比较
//!!!编译错误!!!
//二进制运算符“==”不能应用于两个“服务器”操作数
保护服务器0==服务器1其他{
打印(“同样坏”)
返回
}
打印(“做事情”)
}
最后,我只想比较抽象协议对象之间的差异。其他大多数例子都是比较混凝土类型


我是不是疯了才尝试这个P

如果将函数设置为通用函数,则问题将消失:

func doSomething<T1: Server, T2: Server>(server0: T1, server1: T2) {

该错误的原因相同:
Server
不符合
Server
(听起来很奇怪)。这意味着声明接收协议的函数不能通过向其传递协议来调用,您需要告诉编译器您传递的协议的具体实现

为什么不让
服务器
符合
equalable
?你必须更加小心。多个
ipaddress
可以是不同的字符串,但仍然是相同的服务器。例如,
0:0:0:0:0:0:0:1
::1
@rmaddy Equatable添加了一个
Self
需求,这是一个让人头疼的问题。当遇到此类问题时,停下来想想是否真的需要协议-哪些不同类型的协议符合
服务器
,您会在这些类型中编写哪些通用算法?您可能会发现,
Server
更好地表示为一个符合
equalable
@Alexander的单一结构。服务器协议只是一个例子,有许多其他东西用于区分服务器,为了简单起见,我删除了这些属性。我看到了,有趣的链接。我可以和你们一起讨论几个问题吗,这样我就可以更好地理解静态键入机制了?为什么swift要求传递具体类型信息以进行比较?看来协议定义中的信息就足够了。@Biclops我在答案中添加了更多的细节,如果它回答了您的问题,请告诉我
struct A: Server {
    let ipAddress: String = ""
}

let server1: Server = A()
let server2: Server = A()
print(server1 == server2) // Binary operator '==' cannot be applied to two 'Server' operands