所以,我試圖在使用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