我需要一种比较两种方法的方法,CLLocationCoordinate2D但是当我尝试使用==它时,它是行不通的.请有人帮助我比较它们的最佳方法吗?
对于我的iOS应用程序,我有一个类似的模型
class Person {
var Id: Int
var Name: String
init(id: Int, name: String?) {
self.Id = id
self.Name = name ?? ""
}
}
Run Code Online (Sandbox Code Playgroud)
然后在我ViewController从服务器加载数据时,我将一些人添加到数组中
class ViewController: UIViewController {
var people:[Person] = []
override func viewDidLoad() {
self.loadPeople()
}
func loadPeople() {
// This data will be coming from a server request
// so is just sample. It could have users which
// already exist in the people array
self.people.append(Person(id: "1", name: "Josh"))
self.people.append(Person(id: "2", name: "Ben")) …Run Code Online (Sandbox Code Playgroud) 我不认为这可以做,但无论如何我都会问.我有一个协议:
protocol X {}
Run Code Online (Sandbox Code Playgroud)
一节课:
class Y:X {}
Run Code Online (Sandbox Code Playgroud)
在我的其余代码中,我使用协议X引用所有内容.在该代码中,我希望能够执行以下操作:
let a:X = ...
let b:X = ...
if a == b {...}
Run Code Online (Sandbox Code Playgroud)
问题是,如果我尝试实现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
}
Run Code Online (Sandbox Code Playgroud)
尝试允许使用==隐藏协议背后的实现的想法.
Swift不喜欢这个,因为它Equatable有Self引用,它将不再允许我将它用作类型.仅作为一般参数.
那么有没有人找到一种方法将一个运算符应用于一个协议,而协议不会作为一种类型变得无法使用?
我有以下内容Protocol:
protocol Cacheable {
//....//
func identifier() -> String
}
Run Code Online (Sandbox Code Playgroud)
我可以使Cacheable工具Equatable吗?
当我做以下事情时:
extension Cacheable: Equatable {}
func ==(lhs:Cacheable,rhs:Cacheable) -> Bool {
return lhs.identifier() == rhs.identifier()
}
Run Code Online (Sandbox Code Playgroud)
我收到此错误消息:协议扩展Cacheable不能有继承子句
我已经看到了这个Swift Equatable Protocol问题的答案,该问题提到了如何==在全局范围内声明该方法.
如果我不采用Equatable,我仍然可以声明==测试我的两种类型之间的相等性.
// extension Foo: Equatable {}
func ==(lhs: Foo, rhs: Foo) -> Bool {
return lhs.bar == rhs.bar
}
struct Foo {
let bar:Int
}
Run Code Online (Sandbox Code Playgroud)
它的实现需要在全球范围内声明的事实使得它似乎是偶然的,并且与协议不同,即使Equatable被采用.
Equatable协议如何只是语法糖只是让(我们和)编译器安全地知道我们的类型实现了协议所需的方法?
为什么运算符实现必须全局声明,即使对于协议也是如此?这是由于调度操作员的某种不同方式吗?
我有一个协议类Equatable.这个类看起来像这样:
class Item: Equatable {
let item: [[Modifications: String]]
init(item: [[Modifications: String]]) {
self.item = item
}
}
func ==(lhs: Item, rhs: Item) -> Bool {
return lhs.item == rhs.item
}
Run Code Online (Sandbox Code Playgroud)
但这给了我错误(见标题).该属性item是[[String: String]]以前,没有问题,我不知道如何解决这个问题.我试着谷歌搜索和搜索所有的SO但没有运气..
枚举只是一个简单的基本:
enum Modifications: Int {
case Add = 1
case Remove = 2
case More = 3
case Less = 4
}
Run Code Online (Sandbox Code Playgroud) 如何使结构符合协议"Equatable"?
我正在使用Xcode 7.3.1
struct MyStruct {
var id: Int
var value: String
init(id: Int, value: String) {
self.id = id
self.value = value
}
var description: String {
return "blablabla"
}
}
Run Code Online (Sandbox Code Playgroud)
当我使用"MyStruct"时,Xcode显示错误:
MyStruct不符合协议"Equatable"
你有想法使MyStruct符合协议吗?
FooBar下面的类必须覆盖==该Equatable类型的功能.
但是,调用对象contains数组FooBar不会导致==调用自定义函数内的断点.是否可能其他==功能覆盖此自定义功能?
注意:因为FooBar必须从NSCoding和NSObject继承,所以FooBar不会将Equatable列为协议,因为它会导致此错误:
'FooBar'与协议'Equatable'的冗余一致性
func ==(lhs: FooBar, rhs: FooBar) -> Bool {
return lhs.id == rhs.id
}
class FooBar: NSObject, NSCoding {
// Class def
}
// Both serverFooBars and gFooBars are [FooBar]
let newFooBars = serverFooBars.filter { !gFooBars.contains($0) }
Run Code Online (Sandbox Code Playgroud) 为了解决这个问题,我一直在玩一个实现Hashable Protocol的自定义结构.我正在尝试查看等效运算符overload(==)被调用多少次,具体取决于填充a时是否存在哈希冲突Dictionary.
更新
@matt编写了一个更清晰的自定义结构示例,该结构实现了Hashable协议并显示了调用的频率hashValue和==调用次数.我在下面复制他的代码.要查看我的原始示例,请查看编辑历史记录.
struct S : Hashable {
static func ==(lhs:S,rhs:S) -> Bool {
print("called == for", lhs.id, rhs.id)
return lhs.id == rhs.id
}
let id : Int
var hashValue : Int {
print("called hashValue for", self.id)
return self.id
}
init(_ id:Int) {self.id = id}
}
var s = Set<S>()
for i in 1...5 {
print("inserting", i)
s.insert(S(i))
}
Run Code Online (Sandbox Code Playgroud)
这会产生结果:
/*
inserting 1
called …Run Code Online (Sandbox Code Playgroud) 我有一个关联值的枚举,为了进行测试,我想使其相等,但不知道这种模式如何适用于带有多个参数的枚举实例。
例如,总结如下,我知道使标题相等的语法。对于包含多个不同类型值的选项,这将如何工作?
enum ViewModel {
case heading(String)
case options(id: String, title: String, enabled: Bool)
}
func ==(lhs: ViewModel, rhs: ViewModel) -> Bool {
switch (lhs, rhs) {
case (let .heading(lhsString), let .heading(rhsString)):
return lhsString == rhsString
case options...
default:
return false
}
}
Run Code Online (Sandbox Code Playgroud)
我知道Swift 4.1可以为我们合成Equatable的一致性,但是目前我无法更新到该版本。