简体   繁体   English

Swift Equatable 在协议上

[英]Swift Equatable on a protocol

I don't think this can be done but I'll ask anyway.我不认为这可以做到,但我还是会问。 I have a protocol:我有一个协议:

protocol X {}

And a class:还有一个类:

class Y:X {}

In the rest of my code I refer to everything using the protocol X. In that code I would like to be able to do something like:在我的其余代码中,我使用协议 X 引用所有内容。在该代码中,我希望能够执行以下操作:

let a:X = ...
let b:X = ...
if a == b {...}

The problem is that if I try to implement Equatable :问题是,如果我尝试实现Equatable

protocol X: Equatable {}
func ==(lhs:X, rhs:X) -> Bool {
    if let l = lhs as? Y, let r = hrs as? Y {
        return l.something == r.something
    }
    return false
} 

The idea to try and allow the use of == whilst hiding the implementations behind the protocol.尝试并允许使用==同时隐藏协议背后的实现的想法。

Swift doesn't like this though because Equatable has Self references and it will no longer allow me to use it as a type. Swift 不喜欢这个,因为EquatableSelf引用,它不再允许我将它用作类型。 Only as a generic argument.仅作为通用参数。

So has anyone found a way to apply an operator to a protocol without the protocol becoming unusable as a type?那么有没有人找到一种方法来将运算符应用于协议而不会使协议无法作为类型使用?

I don't think this can be done but I'll ask anyway.我不认为这可以解决,但我还是会问。 I have a protocol:我有一个协议:

protocol X {}

And a class:和一类:

class Y:X {}

In the rest of my code I refer to everything using the protocol X. In that code I would like to be able to do something like:在我的其余代码中,我使用协议X引用所有内容。在该代码中,我希望能够执行以下操作:

let a:X = ...
let b:X = ...
if a == b {...}

The problem is that if I try to implement Equatable :问题是,如果我尝试实现Equatable

protocol X: Equatable {}
func ==(lhs:X, hrs:X) -> Bool {
    if let l = lhs as? Y, let r = hrs as? Y {
        return l.something == r.something
    }
    return false
} 

The idea to try and allow the use of == whilst hiding the implementations behind the protocol.尝试使用==的想法,同时将实现隐藏在协议后面。

Swift doesn't like this though because Equatable has Self references and it will no longer allow me to use it as a type. Swift不喜欢这种方式,因为Equatable具有Self引用,它将不再允许我将其用作类型。 Only as a generic argument.仅作为通用参数。

So has anyone found a way to apply an operator to a protocol without the protocol becoming unusable as a type?那么,有没有人找到一种将操作符应用到协议的方法,而又不会使该协议不能用作一种类型?

I don't think this can be done but I'll ask anyway.我不认为这可以解决,但我还是会问。 I have a protocol:我有一个协议:

protocol X {}

And a class:和一类:

class Y:X {}

In the rest of my code I refer to everything using the protocol X. In that code I would like to be able to do something like:在我的其余代码中,我使用协议X引用所有内容。在该代码中,我希望能够执行以下操作:

let a:X = ...
let b:X = ...
if a == b {...}

The problem is that if I try to implement Equatable :问题是,如果我尝试实现Equatable

protocol X: Equatable {}
func ==(lhs:X, hrs:X) -> Bool {
    if let l = lhs as? Y, let r = hrs as? Y {
        return l.something == r.something
    }
    return false
} 

The idea to try and allow the use of == whilst hiding the implementations behind the protocol.尝试使用==的想法,同时将实现隐藏在协议后面。

Swift doesn't like this though because Equatable has Self references and it will no longer allow me to use it as a type. Swift不喜欢这种方式,因为Equatable具有Self引用,它将不再允许我将其用作类型。 Only as a generic argument.仅作为通用参数。

So has anyone found a way to apply an operator to a protocol without the protocol becoming unusable as a type?那么,有没有人找到一种将操作符应用到协议的方法,而又不会使该协议不能用作一种类型?

I don't think this can be done but I'll ask anyway.我不认为这可以解决,但我还是会问。 I have a protocol:我有一个协议:

protocol X {}

And a class:和一类:

class Y:X {}

In the rest of my code I refer to everything using the protocol X. In that code I would like to be able to do something like:在我的其余代码中,我使用协议X引用所有内容。在该代码中,我希望能够执行以下操作:

let a:X = ...
let b:X = ...
if a == b {...}

The problem is that if I try to implement Equatable :问题是,如果我尝试实现Equatable

protocol X: Equatable {}
func ==(lhs:X, hrs:X) -> Bool {
    if let l = lhs as? Y, let r = hrs as? Y {
        return l.something == r.something
    }
    return false
} 

The idea to try and allow the use of == whilst hiding the implementations behind the protocol.尝试使用==的想法,同时将实现隐藏在协议后面。

Swift doesn't like this though because Equatable has Self references and it will no longer allow me to use it as a type. Swift不喜欢这种方式,因为Equatable具有Self引用,它将不再允许我将其用作类型。 Only as a generic argument.仅作为通用参数。

So has anyone found a way to apply an operator to a protocol without the protocol becoming unusable as a type?那么,有没有人找到一种将操作符应用到协议的方法,而又不会使该协议不能用作一种类型?

I don't think this can be done but I'll ask anyway.我不认为这可以解决,但我还是会问。 I have a protocol:我有一个协议:

protocol X {}

And a class:和一类:

class Y:X {}

In the rest of my code I refer to everything using the protocol X. In that code I would like to be able to do something like:在我的其余代码中,我使用协议X引用所有内容。在该代码中,我希望能够执行以下操作:

let a:X = ...
let b:X = ...
if a == b {...}

The problem is that if I try to implement Equatable :问题是,如果我尝试实现Equatable

protocol X: Equatable {}
func ==(lhs:X, hrs:X) -> Bool {
    if let l = lhs as? Y, let r = hrs as? Y {
        return l.something == r.something
    }
    return false
} 

The idea to try and allow the use of == whilst hiding the implementations behind the protocol.尝试使用==的想法,同时将实现隐藏在协议后面。

Swift doesn't like this though because Equatable has Self references and it will no longer allow me to use it as a type. Swift不喜欢这种方式,因为Equatable具有Self引用,它将不再允许我将其用作类型。 Only as a generic argument.仅作为通用参数。

So has anyone found a way to apply an operator to a protocol without the protocol becoming unusable as a type?那么,有没有人找到一种将操作符应用到协议的方法,而又不会使该协议不能用作一种类型?

I don't think this can be done but I'll ask anyway.我不认为这可以解决,但我还是会问。 I have a protocol:我有一个协议:

protocol X {}

And a class:和一类:

class Y:X {}

In the rest of my code I refer to everything using the protocol X. In that code I would like to be able to do something like:在我的其余代码中,我使用协议X引用所有内容。在该代码中,我希望能够执行以下操作:

let a:X = ...
let b:X = ...
if a == b {...}

The problem is that if I try to implement Equatable :问题是,如果我尝试实现Equatable

protocol X: Equatable {}
func ==(lhs:X, hrs:X) -> Bool {
    if let l = lhs as? Y, let r = hrs as? Y {
        return l.something == r.something
    }
    return false
} 

The idea to try and allow the use of == whilst hiding the implementations behind the protocol.尝试使用==的想法,同时将实现隐藏在协议后面。

Swift doesn't like this though because Equatable has Self references and it will no longer allow me to use it as a type. Swift不喜欢这种方式,因为Equatable具有Self引用,它将不再允许我将其用作类型。 Only as a generic argument.仅作为通用参数。

So has anyone found a way to apply an operator to a protocol without the protocol becoming unusable as a type?那么,有没有人找到一种将操作符应用到协议的方法,而又不会使该协议不能用作一种类型?

I don't think this can be done but I'll ask anyway.我不认为这可以解决,但我还是会问。 I have a protocol:我有一个协议:

protocol X {}

And a class:和一类:

class Y:X {}

In the rest of my code I refer to everything using the protocol X. In that code I would like to be able to do something like:在我的其余代码中,我使用协议X引用所有内容。在该代码中,我希望能够执行以下操作:

let a:X = ...
let b:X = ...
if a == b {...}

The problem is that if I try to implement Equatable :问题是,如果我尝试实现Equatable

protocol X: Equatable {}
func ==(lhs:X, hrs:X) -> Bool {
    if let l = lhs as? Y, let r = hrs as? Y {
        return l.something == r.something
    }
    return false
} 

The idea to try and allow the use of == whilst hiding the implementations behind the protocol.尝试使用==的想法,同时将实现隐藏在协议后面。

Swift doesn't like this though because Equatable has Self references and it will no longer allow me to use it as a type. Swift不喜欢这种方式,因为Equatable具有Self引用,它将不再允许我将其用作类型。 Only as a generic argument.仅作为通用参数。

So has anyone found a way to apply an operator to a protocol without the protocol becoming unusable as a type?那么,有没有人找到一种将操作符应用到协议的方法,而又不会使该协议不能用作一种类型?

I don't think this can be done but I'll ask anyway.我不认为这可以解决,但我还是会问。 I have a protocol:我有一个协议:

protocol X {}

And a class:和一类:

class Y:X {}

In the rest of my code I refer to everything using the protocol X. In that code I would like to be able to do something like:在我的其余代码中,我使用协议X引用所有内容。在该代码中,我希望能够执行以下操作:

let a:X = ...
let b:X = ...
if a == b {...}

The problem is that if I try to implement Equatable :问题是,如果我尝试实现Equatable

protocol X: Equatable {}
func ==(lhs:X, hrs:X) -> Bool {
    if let l = lhs as? Y, let r = hrs as? Y {
        return l.something == r.something
    }
    return false
} 

The idea to try and allow the use of == whilst hiding the implementations behind the protocol.尝试使用==的想法,同时将实现隐藏在协议后面。

Swift doesn't like this though because Equatable has Self references and it will no longer allow me to use it as a type. Swift不喜欢这种方式,因为Equatable具有Self引用,它将不再允许我将其用作类型。 Only as a generic argument.仅作为通用参数。

So has anyone found a way to apply an operator to a protocol without the protocol becoming unusable as a type?那么,有没有人找到一种将操作符应用到协议的方法,而又不会使该协议不能用作一种类型?

I don't think this can be done but I'll ask anyway.我不认为这可以解决,但我还是会问。 I have a protocol:我有一个协议:

protocol X {}

And a class:和一类:

class Y:X {}

In the rest of my code I refer to everything using the protocol X. In that code I would like to be able to do something like:在我的其余代码中,我使用协议X引用所有内容。在该代码中,我希望能够执行以下操作:

let a:X = ...
let b:X = ...
if a == b {...}

The problem is that if I try to implement Equatable :问题是,如果我尝试实现Equatable

protocol X: Equatable {}
func ==(lhs:X, hrs:X) -> Bool {
    if let l = lhs as? Y, let r = hrs as? Y {
        return l.something == r.something
    }
    return false
} 

The idea to try and allow the use of == whilst hiding the implementations behind the protocol.尝试使用==的想法,同时将实现隐藏在协议后面。

Swift doesn't like this though because Equatable has Self references and it will no longer allow me to use it as a type. Swift不喜欢这种方式,因为Equatable具有Self引用,它将不再允许我将其用作类型。 Only as a generic argument.仅作为通用参数。

So has anyone found a way to apply an operator to a protocol without the protocol becoming unusable as a type?那么,有没有人找到一种将操作符应用到协议的方法,而又不会使该协议不能用作一种类型?

I don't think this can be done but I'll ask anyway.我不认为这可以解决,但我还是会问。 I have a protocol:我有一个协议:

protocol X {}

And a class:和一类:

class Y:X {}

In the rest of my code I refer to everything using the protocol X. In that code I would like to be able to do something like:在我的其余代码中,我使用协议X引用所有内容。在该代码中,我希望能够执行以下操作:

let a:X = ...
let b:X = ...
if a == b {...}

The problem is that if I try to implement Equatable :问题是,如果我尝试实现Equatable

protocol X: Equatable {}
func ==(lhs:X, hrs:X) -> Bool {
    if let l = lhs as? Y, let r = hrs as? Y {
        return l.something == r.something
    }
    return false
} 

The idea to try and allow the use of == whilst hiding the implementations behind the protocol.尝试使用==的想法,同时将实现隐藏在协议后面。

Swift doesn't like this though because Equatable has Self references and it will no longer allow me to use it as a type. Swift不喜欢这种方式,因为Equatable具有Self引用,它将不再允许我将其用作类型。 Only as a generic argument.仅作为通用参数。

So has anyone found a way to apply an operator to a protocol without the protocol becoming unusable as a type?那么,有没有人找到一种将操作符应用到协议的方法,而又不会使该协议不能用作一种类型?

I don't think this can be done but I'll ask anyway.我不认为这可以解决,但我还是会问。 I have a protocol:我有一个协议:

protocol X {}

And a class:和一类:

class Y:X {}

In the rest of my code I refer to everything using the protocol X. In that code I would like to be able to do something like:在我的其余代码中,我使用协议X引用所有内容。在该代码中,我希望能够执行以下操作:

let a:X = ...
let b:X = ...
if a == b {...}

The problem is that if I try to implement Equatable :问题是,如果我尝试实现Equatable

protocol X: Equatable {}
func ==(lhs:X, hrs:X) -> Bool {
    if let l = lhs as? Y, let r = hrs as? Y {
        return l.something == r.something
    }
    return false
} 

The idea to try and allow the use of == whilst hiding the implementations behind the protocol.尝试使用==的想法,同时将实现隐藏在协议后面。

Swift doesn't like this though because Equatable has Self references and it will no longer allow me to use it as a type. Swift不喜欢这种方式,因为Equatable具有Self引用,它将不再允许我将其用作类型。 Only as a generic argument.仅作为通用参数。

So has anyone found a way to apply an operator to a protocol without the protocol becoming unusable as a type?那么,有没有人找到一种将操作符应用到协议的方法,而又不会使该协议不能用作一种类型?

took some of the code from above and came with the following sollution.从上面获取了一些代码,并提供了以下解决方案。

it uses the IsEqual protocol instead of the Equatable protocol and with a few line codes you will be able to compare any two protocol objects with each other, wether they are optional or not, are in an array and even add comparing dates while I was at it.它使用 IsEqual 协议而不是 Equatable 协议,并且通过几行代码,您将能够将任何两个协议对象相互比较,无论它们是否可选,是否在数组中,甚至在我在时添加比较日期它。

protocol IsEqual {
    func isEqualTo(_ object: Any) -> Bool
}

func == (lhs: IsEqual?, rhs: IsEqual?) -> Bool {
    guard let lhs = lhs else { return rhs == nil }
    guard let rhs = rhs else { return false }
    return lhs.isEqualTo(rhs) }

func == (lhs: [IsEqual]?, rhs: [IsEqual]?) -> Bool {
    guard let lhs = lhs else { return rhs == nil }
    guard let rhs = rhs else { return false }
    
    guard lhs.count == rhs.count else { return false }
    for i in 0..<lhs.count {
        if !lhs[i].isEqualTo(rhs[i]) {
            return false
        }
    }
    return true
}

func == (lhs: Date?, rhs: Date?) -> Bool {
    guard let lhs = lhs else { return rhs == nil }
    guard let rhs = rhs else { return false }
    
    return lhs.compare(rhs) == .orderedSame
}

protocol Pet: IsEqual {
  var age: Int { get }
}

struct Dog: Pet {
  let age: Int
  let favoriteFood: String

  func isEqualTo(_ object: Any) -> Bool {
    guard let otherDog = object as? Dog else { return false }

    return age == otherDog.age && favoriteFood == otherDog.favoriteFood
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM