2014-06-07 21 views
5

podany kodJak wywołać metodę niejednoznaczną?

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} 

nie można skompilować z komunikatem o błędzie

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

więc wygląda mi pozwolił stworzyć metodę rozszerzenia metodą duplikowane i podpisem, ale jakoś trzeba w szczególny sposób nazwać


BTW, domyślnie Array.filter jest uszkodzona, to wywołuje zamknięcie dwukrotnie dla każdego elementu i wywala R EPL lub dać wynik śmieci na placu zabaw, jeśli wynik jest sprzeczny

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

Dobre pytanie. Tylko moje 2 centy: nawet w Objective-C nadpisanie istniejącej metody przy użyciu kategorii może spowodować UB, prawda? Być może Swift ma do tego wzmocnienie? Popraw mnie, jeśli się mylę. – Unheilig

+0

@Unheilig tak to UB w ObjC. ale to jest trochę inne. nadal pozwala mi ** dodać ** (nie zastępować) nową metodę o tej samej nazwie. ale po prostu nie pozwól mi tego nazwać. obrazując pewną skompilowaną bibliotekę, która już używa metody 'filter', myślę, że nadal będzie działała i użyje domyślnej (zakładając, że szybkie wywołanie statyczne to wywoła). –

+0

Niezła robota detektywistyczna na "filtrze"! Nie zapomnij złożyć zgłoszenia błędu. – matt

Odpowiedz

2

Nie ma problemu z określeniem metod niejednoznaczne, myślę. Problem pojawia się, gdy użytkownik nanosi różne metody z różnych modułów. Niestety, nie można wyłączyć importowania Array.filter.

Zrobiłem kilka testów i wydaje mi się zachowanie dla definicji niejednoznaczną nie jest dobrze zdefiniowany, na przykład:

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" 

Zachowanie może być różny dla klas obj-c ...

W przypadku funkcji wydaje się, że preferowana jest definicja z bieżącego modułu:

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}" 
Powiązane problemy