2014-06-07 31 views
5

給這個代碼如何調用模糊方法?

extension Array { 
    func filter(includeElement: (T) -> Bool) -> T[] { 
     var ret = T[]() 
     for e in self { 
      if includeElement(e) { 
       ret += e 
      } 
     } 
     return ret 
    } 
} 

var a = [1,2] 
var b = a.filter() {i in print(i); return true} 

它無法與錯誤消息編譯

error: ambiguous use of 'filter' 
var b = a.filter() {i in print(i); return true} 
     ^
Swift.Array<T>:84:8: note: found this candidate 
    func filter(includeElement: (T) -> Bool) -> Array<T> 
    ^
<REPL>:30:10: note: found this candidate 
    func filter(includeElement: (T) -> Bool) -> T[] { 
     ^

所以看起來像我可以創建擴展方法與重複法和簽名,但我有點需要一種特殊的方式稱它爲


順便說一句,默認Array.filter被打破時,它調用關閉兩次,每次元件和崩潰ř如果結果不一致,EPL或在操場上給你的垃圾結果

xiliangchen-imac:~ xiliangchen$ xcrun swift 
Welcome to Swift! Type :help for assistance. 
    1> let arr = [1,2,3,4,5] 
arr: Int[] = size=5 { 
    [0] = 1 
    [1] = 2 
    [2] = 3 
    [3] = 4 
    [4] = 5 
} 
    2> var i = 0 
i: Int = 0 
    3> let arr2 = arr.filter() { 
    4.   println($0) 
    5.   return i++ < 5 
    6. } 
Segmentation fault: 11 
+0

好問題。只是我的2美分:即使在Objective-C覆蓋現有的方法使用類別可能會導致UB,對吧?也許斯威夫特對此有所強化?糾正我,如果我錯了。 – Unheilig

+0

@Unheilig是的,它是UB在ObjC。但這有點不同。它仍然允許我**添加**(不覆蓋)具有相同名稱的新方法。但只是不允許我打電話給他。我已經使用'filter'方法對一些已編譯的庫進行了成像,我認爲它仍然可以工作並使用默認的(假設使用靜態調度來快速調用它)。 –

+0

不錯的偵探工作'過濾器'!不要忘記提交錯誤報告。 – matt

回答

2

我認爲定義歧義方法沒有問題。 導入 2來自不同模塊的ambiguos方法會出現問題。不幸的是,沒有辦法如何排除Array.filter被導入。

我做了一些測試,它似乎我要ambigious定義的行爲是不明確的,例如:

extension NSString { 
    func hasPrefix(aString: String!) -> Bool { 
     return false 
    } 
} 

let string: NSString = "test" 

var hasPrefix = string.hasPrefix("t") 
println("Has prefix: \(hasPrefix)") //prints "true" 

var method = string.hasPrefix 
hasPrefix = method("t") 

println("Has prefix: \(hasPrefix)") //prints "false" 

行爲可能是OBJ-C類不同...

對於功能來說,看起來來自當前模塊的定義是優選的:

func NSStringFromCGPoint(point: CGPoint) -> String! { 
    return "My method" 
} 

var point = CGPoint(x: 10.0, y: 10.0) 

println("Point: \(NSStringFromCGPoint(point))") //Prints "My method" 
println("Point: \(UIKit.NSStringFromCGPoint(point))") //Prints "{10, 10}"