2014-06-07 12 views
5

o hata iletisiyle derleme olamaz bu koduBelirsiz yöntem nasıl aranır?

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} 

verilen

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[] { 
     ^

Ben yinelenen yöntem ve imzası ile uzatma yöntemi oluşturmasına izin am gibi pek görünüyor, ama ben bir şekilde özel bir yola ihtiyacımız var adlandırmak

BTW, varsayılan Array.filter bozuldu

, her element için iki kez kapatma çağırır ve R çöküyor Sonuç belirsiz yöntemleri tanımlayan ile hiçbir sorun yoktur

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

İyi soru. Sadece 2 sentim: Objective-C'de bile, kategoriyi kullanarak mevcut yöntemi geçersiz kılmak UB'ye neden olabilir, değil mi? Belki Swift'in buna karşı takviyesi var mı? Eğer Yanlışsam beni düzelt. – Unheilig

+0

@Unheilig evet ObjC'de UB'dir. ama bu farklı bir şey. hala ** aynı adı taşıyan ** yeni bir yöntem eklemem için bana izin ver. ama sadece onu aramama izin vermiyor. zaten 'filtre' yöntemini kullanarak derlenmiş kütüphaneyi görüntüleme, hala çalışır ve varsayılan olanı kullanacağını düşünüyorum (bunu kullanmak için hızlı kullanım statik gönderim varsayılarak). –

+0

'filter' üzerinde güzel dedektif çalışması! Bir hata raporu yazmayı unutma. – matt

cevap

2

tutarsız ise EPL oyun içinde çöp sonucunu verebilir veya sanırım. Sorun, farklı modüllerden içe aktarma 2 ambiguos yöntemini kullandığınızda ortaya çıkar. Ne yazık ki, Array.filter'un içe aktarılmasının nasıl engelleneceğinin bir yolu yoktur.

bazı testler yaptım ve iyi örneğin tanımlanmamış bana kuşkulu tanımları için davranışını görünür:

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" 

davranış obj-c sınıfları için farklı olabilir ...

Fonksiyonlar için, mevcut modülün tanımı tercih edilir:

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}"