协议操作符为什么必须作为全局函数来实现?

我已经看到了这个Swift Equatable Protocol问题的答案,它提到了如何在全局范围内声明==方法。

如果我不采用Equatable ,我仍然可以声明==来testing我的两个types之间的平等。

 // extension Foo: Equatable {} func ==(lhs: Foo, rhs: Foo) -> Bool { return lhs.bar == rhs.bar } struct Foo { let bar:Int } 

其实施需要在全球范围内进行宣布的事实,使得它似乎与议定书是偶然的 ,并且议定书有所不同 ,即使通过了“ Equatable

Equatable协议如何超过语法糖,仅仅让我们和编译器安全地知道我们的types实现了协议所需要的方法?

为什么运营商的实施必须在全球范围内宣布,即使对于协议? 这是否由于运营商派遣的不同方式?

UPDATE

从Xcode 8 beta 4发行说明:

运营商可以在其types或扩展中定义。 例如:

 struct Foo: Equatable { let value: Int static func ==(lhs: Foo, rhs: Foo) -> Bool { return lhs.value == rhs.value } } 

这些操作符必须被声明为static (或者在一个类, class final一个class final ),并且和全局对象具有相同的签名。 作为这种改变的一部分,协议中声明的操作符要求也必须明确声明为static

 protocol Equatable { static func ==(lhs: Self, rhs: Self) -> Bool } 

原版的

近期(2016-01-31至2016-02-09)在快速发展名单上进行了讨论。 Chris Lattner说:关于在结构体或类的作用域中声明运算符:

是的,这是一个普遍需要的function(至less对于对称运算符)。 在类声明中dynamic调度运算符也是很好的。 我不认为我们有一个坚定的build议,确定名称查找是如何工作的。

后来(回复Haravikk):

什么是名字查询问题? 你的意思是Foo == Foo的运算符存在于多个位置吗?

是。 名称查找必须有一个明确的search顺序,它定义了阴影和无效的多个定义规则。

就个人而言,我只是坚持我们现在所拥有的东西,即 – 将特定类/结构中的运算符实现视为全局定义,并且如果同一个签名被声明了多次,则会抛出错误。

我们需要多个模块来定义运营商的实例,我们需要运营商在扩展,我们需要追溯符合工作,如任何其他成员。

来自文档的说明

运算符函数被定义为一个全局函数,其函数名称与要重载的运算符相匹配。

该函数是全局定义的,而不是作为目标类或结构的方法,因此它可以在目标类或结构的现有实例之间用作中缀运算符。

我用通用expression式目标类或结构在引用中replace了具体结构( Vector2D )的名称

其实施需要在全球范围内进行宣布的事实,使得它似乎与议定书是偶然的,并且与议定书有所不同,即使通过了“可接受的等值”。

无论是需要全局函数,类方法还是实例方法,每个协议都是如此。 你总是可以执行一些事情,而不pipe是否有一个协议需要它。

Equatable协议如何超过语法糖,仅仅让我们和编译器安全地知道我们的types实现了协议所需要的方法?

这不是糖。 这是协议的定义和协议的全部要点。 它告诉你,这种types可以应用这些东西。

为什么运营商的实施必须在全球范围内宣布,即使对于协议? 这是否由于运营商派遣的不同方式?

因为这是Swift语法。 运算符函数实现必须是全局函数。 Swift团队有兴趣改变这一点,使其更加一致,但是今天这就是Swift的工作原理。

在Swift标准库中,定义了“==”运算符。 它不具有关联的一方或另一方的比较,并且在整个Swift操作符顺序中具有编号的优先顺序。 你可以检查这个,如果你CMD点击Swift上的“导入Swift”

 infix operator == { associativity none precedence 130 } 

对于Int's,图书馆已经将Int / Int8 / Int16 / Int32 / Int64设置为Equatable:

 public func ==(lhs: Int, rhs: Int) -> Bool 

就像许多其他types一样。

Int在一个扩展中做成了Hashable(在那里符合该协议,你需要创build一个var hashValue:Int {get},它对应用程序的每次执行都会改变:

 extension Int : Hashable { public var hashValue: Int { get } } 

一般来说,运算符'=='和协议需要在struct / enum / class之外的顶层进行声明,因为你正在扩展语言,现在,这就是swift编译的方式。 所有Swift的运算符都是在全局范围内定义的属性。

对于你的“Foo”,你通过添加func来采用Equatable:

 func ==(lhs: Foo, rhs: Foo) -> Bool { return lhs.bar == rhs.bar } 

在协议中使用“Self”本地variables:

 public protocol Equatable { public func ==(lhs: Self, rhs: Self) -> Bool }