所以,我试图在使用SpriteKit时使用gd CGPoint
,CGVector
和CGSize
对我很好。所有这些只是具有垂直和水平分量(向量)的结构。所以,我提出的协议:VectorType
对'!='运算符的模糊使用
protocol VectorType {
init(x: CGFloat, y: CGFloat)
var x: CGFloat { get set }
var y: CGFloat { get set }
}
当然,我延长了3层结构,以符合协议并连接x
和y
到的每个结构体即水平和垂直分量x
返回dx
为CGVector
(同样为设置),x
返回width
为CGSize
,并且CGPoint
什么都没有,因为它们开箱即用,只是将扩展名留空。
现在我重载了“主要”操作符(+ - * /
...),所以我可以毫不费力地执行涉及不同类型结构的操作,而无需投射它们或创建新对象,但这里最主要的是我也重载了等价运营商这样的:
//Compiler requires me to use generics for some reason
func == <T: VectorType, U: VectorType> (lhs: T, rhs: U) -> Bool {
return (lhs.x == rhs.x) && (lhs.y == rhs.y)
}
func != <T: VectorType, U: VectorType> (lhs: T, rhs: U) -> Bool {
return !(lhs == rhs)
}
现在,当我测试此代码一切除了!=
运营商的罚款。为了测试这些运算符,我将尺寸与尺寸,尺寸与向量以及尺寸与每个类型的点等进行了比较。当我使用==
时,没有问题。
但后来,当我使用!=
有问题。有一个Ambiguous use of operator '!='
这样的:
我完全得到这哪里是来自:重载的==
和!=
运营商比较CGVector to CGVector
,CGPoint to CGPoint
和CGSize to CGSize
已经存在。他们被宣布是这样的
@warn_unused_result func ==(lhs: CGSize, rhs: CGSize) -> Bool
每种类型的课程都有过载。所以我得到了模糊性来自哪里,在比较相同的类型时,它不知道使用哪个运算符。但我不明白为什么在testEqual()
的==
运营商没有这样的问题,如果我们基本上有相同的情况。
这似乎是一个编译器bug,但我不确定,我试图清理项目,重新启动Xcode,并创建一个新的项目,但仍然无法正常工作。此外,当我试图看到导致歧义的另一个声明选择Found this candidate
时,它只是不显示任何内容。
所以,问题是:我该如何使它工作,或者你能否提出另一种方法使其工作(不涉及创建不同的操作员)?
更新
我发现实际使用的==
和!=
实现实际上是宣告不同。这是如何被使用的==
超载声明
@warn_unused_result func ==(lhs: CGSize, rhs: CGSize) -> Bool
AFAIK这也应该与我的声明相冲突,但它显然并非如此。
这里是另一个!=
重载声明。
@warn_unused_result func !=<T : Equatable>(lhs: T, rhs: T) -> Bool
由于lhs
和rhs
具有相同的类型和所有三种类型的符合VectorType协议符合Equatable
此重载是用于该操作的候选者。
我猜==
被使用,因为它明确地要求一个CGVector
,CGPoint
或CGSize
,或许接管泛型的优先级。不知道让我知道,如果你知道为什么两个==
运营商不冲突。
如果你不重写'!='定义会发生什么?它的默认实现基于'not ==' – Alexander
顺便说一句,不要为自己的类型使用'CG'前缀。它通常保留CoreGraphics – Alexander
嗯,我想我可以做到这一点,但它不觉得正确,我将需要手动比较这是我想要避免,但如果找不到另一个解决方案是我会走的路。是的,我正在考虑CG的事情,我会改变它,这只是我命名时首先想到的。 – lsauceda