Использование equals на двух объектах протокола

В идеале сервер должен был бы реализовать протокол Equatable, но я столкнулся с проблемами. Вот мой код

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")
}

В конечном итоге я просто хочу сравнить абстрактные объекты протокола друг с другом. Большинство других примеров сравнивают конкретные типы.

Я схожу с ума от этого или что?:П

1 ответ

Решение

Ваша проблема исчезнет, ​​если вы сделаете функцию общей:

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

Это необходимо, потому что протоколы Swift не соответствуют базовым протоколам, даже самим себе. Добавление общего предложения изменяет функцию с абстрактной на конкретную, основываясь на аргументах, передаваемых при вызове.

Та же ошибка происходит для следующего кода:

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

Ошибка имеет ту же причину: Server не соответствует Server (как бы странно это ни звучало). Это означает, что функция, объявляющая получение протокола, не может быть вызвана путем передачи ему протокола, вам нужно сообщить компилятору, какую конкретную реализацию протокола вы передаете.

Другие вопросы по тегам