想必您在代碼中有import Cocoa
或import Foundation
。如果你刪除它,你會發現你的代碼按照你的預期行事。
發生這種情況的原因是,在導入基金會導致Swift.Array
神奇地橋接到NSArray
(又名[AnyObject]
),和某些原始值類型神奇地橋接到Foundation對象類型(如NSString
和NSNumber
)。一旦發生這種情況,使用[AnyObject]
和AnyObject
類型的參數調用函數是完全合法的。
我不知道周圍的魔力轉化好方式,但工作的方法之一是迫使你的泛型參數有原始值的類型遵循的協議,但基本值神奇包裹在可可物體中沒有。以確保這樣的一種方法是創建自己的協議:
public protocol NotAnyObject {}
extension Int: NotAnyObject {}
extension String: NotAnyObject {}
extension Double: NotAnyObject {}
func findAll<T: Equatable where T: NotAnyObject>(arr: [T], _ elem: T) -> [Int] { /*...*/ }
我不知道這是最好的辦法,但...替代方案是受歡迎的。
順便提及,更慣用/ SWIFTY方式這樣做將是作爲一個類型擴展(或者一個協議擴展,如下,或上一個Array where Element: Equatable
擴展)。你甚至可以去功能編程風格只是爲了好玩:
extension CollectionType where Generator.Element : Equatable {
public func allIndexesOf(element: Self.Generator.Element) -> [Self.Index] {
return zip(self.indices, self) // makes sequence of (index, element)
.filter { $0.1 == element }
.map { $0.0 }
}
}
這樣稱呼它:
let threes = [5, 3, 7, 3, 9].allIndexesOf(3)
// returns [1, 3]
這仍然是受同樣的魔力轉換的問題,雖然:
let notThrees = ["twenty", "forty", "eight"].allIndexesOf[2.0]
// still compiles, returns []
所以你仍然需要使用這個擴展名,只能從沒有導入Foundation的Swift文件中使用這個擴展名,或者應用與上面相同的hack的變體,例如:
extension CollectionType where Generator.Element: Equatable,
Generator.Element: NotAnyObject { /*...*/ }
我同意這個解釋,我不同意這個建議的解決方案,刪除'Foundation'的輸入通常是不可能的。 – Sulthan
非常感謝rickster和@Sulthan!這兩個答案真的幫助我!試圖upvote,但看起來像stackoverflow以另一種方式認爲:) – FlyOrDie
這種橋接真的讓我難過:/開發IOS應用程序時,這樣的問題真的很麻煩嗎?哦,這只是一件要知道的事情,但不是真的有問題? – FlyOrDie