2015-05-04 10 views
6

Mam protokół, który wykorzystuje przypisany typ, jako takich:testowania protokół zgodności z powiązanymi typów

protocol Populatable { 
    typealias T 
    func populateWith(object: T) 
} 

i klas, które implementują protokołu:

class DateRowType: Populatable { 
    func populateWith(object: NSDate) { 
     print(object.description) 
    } 
} 

class StringRowType : Populatable { 
    func populateWith(object: String) { 
     print(object) 
    } 
} 

ale gdy próbuję rzucić lub Test zgodności, tak:

let drt = DateRowType() 
let srt = StringRowType() 

let rowTypes = [drt, srt] 
let data = [NSDate(), "foo"] 

for (i, p: Populatable) in enumerate(rowTypes) { 
    p.populateWith(data[i]) 
} 

pojawia się błąd:

Protocol 'Populatable' can only be used as a generic constraint because it has Self or associated type requirements

Jaki jest prawidłowy sposób na sprawdzenie, czy obiekt jest zgodny z protokołem Populatable?

Uwaga: cały kod wymagany do wypróbowania tego jest zawarty w pytaniu, po prostu skopiuj bloki kodu na plac zabaw.

+0

Chcę mieć inne klasy typów wierszy, które przyjmują inne typy jako parametr funkcji wypełnienia. Obecnie tablica zdarzeń jest heterogeniczna, ale w przyszłości może zawierać wiele typów implementujących protokół Populatable. – Senior

+0

Każdy wiersz zostanie wypełniony przez inny typ, więc chcę, aby mój protokół był ogólny, aby jeden wiersz mógł go zaimplementować jako wypełnienie (obiekt: Zdarzenie), inny może zostać wypełniony (obiekt: Zespół) itp. Bez bycia generic I musiałbym sprawić, by użycie protokołu zapełniło się (obiekt: AnyObject), co eliminuje wiele radości z używania Swift. Zapełnienie – Senior

+0

nie zajmuje Populatable, jest zawarte w protokole Populatable. Populatable definiuje metodę na innej klasie, w tym przypadku NSObject do używania jako kontrolerów WKInterfaceTable. – Senior

Odpowiedz

0

Jak informuje błąd, nie można go przesłać do Populatable tutaj. Myślę, że prawidłowym sposobem jest rzutowanie go na EventRowType.

if let rowController = self.table.rowControllerAtIndex(i) as? EventRowType { 

I już przetestowano, że klasa "EventRowType" jest zgodna z protokołem "Populatable". Bo jeśli EventRowType nie posiada funkcję o nazwie „Populate”, szybki kompilator mówi

Type 'EventRowType' does not conform to protocol 'Populatable'

+0

Tak, niestety chcę, aby to było ogólne i działało z wieloma typami wierszy, które implementują protokół Populatable. Czy istnieje jakiś sposób, aby to zrobić? – Senior

+0

Myślę, że nie ma mowy. Jeśli chcesz, aby był ogólny, musisz podać informacje o typie kompilatora podczas kompilacji. – Satachito

+0

Czy istnieje sposób na opisanie protokołu lub deklaracji informującej kompilator? – Senior

0

nie sądzę, będzie można przejść całą drogę rodzajowy, chyba że ewentualnie za pomocą AnyObject i testowanie klasę parametru w każdym populmie z funkcją.

Ale to będzie działać:

for (i, p) in enumerate(rowTypes) { 
    if let dateRow = p as? DateRowType { 
     dateRow.populateWith(data[i] as! NSDate) 
    } 
    else if let stringRow = p as? StringRowType { 
     stringRow.populateWith(data[i] as! String) 
    } 
} 

Będziesz wystarczy poszerzyć to dla każdej klasy Populatable Państwo dodać.

+0

Dzięki, miałem nadzieję, że będą automatycznie obsługiwane przez generycznych. Czy jestem szalony czy jest to możliwe w Javie/C#? – Senior

+0

Tak jak ty, pomyślałem, że powinno działać z lekami generycznymi, ale nie używałem ich zbyt wiele. – SarahR

Powiązane problemy