2016-10-27 9 views
2

Ich möchte ein Protokoll, das einige Methoden und Eigenschaften definiert. Merkmalstypen und Methodenrückgabetypen können jedoch zwischen den verschiedenen Klassen variieren, die dem Protokoll entsprechen. Zum Beispiel: A.getContent() kann einen Wert vom Typ String zurückgeben, aber B.getContent() kann einen Wert vom Typ Int zurückgeben. In meinem Beispiel unten verwendete ich den Typ Any. Ist das in Swift möglich oder ist das ein völlig falscher Ansatz? Vielleicht mit Generika?Verschiedene Rückgabetypen von Protokollmethode

protocol Content { 
    func getContent() -> any 
} 

class A: Content { 
    func getContent() -> String { 
     return "Im a String" 
    } 
} 

class B: Content { 
    func getContent() -> Int { 
     return 1234 
    } 
} 
+1

Werfen Sie einen Blick auf den Abschnitt [zugehörige Typen im Swift-Programmiersprachenhandbuch] (https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Generics.html#//apple_ref/doc/uid/TP40014097-CH26 -ID189) :) – Hamish

+0

Vielleicht mit Generika. – matt

Antwort

1

können Sie Generika verwenden und Meta-Typen:

protocol Content { 
    func getContent<T>(ofType: T.Type) -> T? 
} 

class A: Content { 
    func getContent<T>(ofType: T.Type) -> T? { 
     return "Im a String" as? T ?? nil 
    } 
} 

class B: Content { 
    func getContent<T>(ofType: T.Type) -> T? { 
     return 1234 as? T ?? nil 
    } 
} 

let aClass = A() 
let aValue = aClass.getContent(ofType: String.self) // "Im a String" 

let bClass = B() 
let bValue = bClass.getContent(ofType: Int.self) // 1234 
4

Ich glaube, Sie suchen über Generics im Protokoll Nr. Sie können mit associatedtype einen Typ dynamisch zuordnen, zB

protocol Content{ 
    associatedtype T 
    func getContent()-> T 
} 

class A: Content { 
    func getContent() -> String { 
     return "Hello World" 
    } 
} 

class B: Content { 
    func getContent() -> Int { 
     return 42 
    } 
} 

A().getContent() //"Hello World" 
B().getContent() //42 

Wenn Sie dieses Beispiel aussehen, wenn Sie den Typ nach Funktion in der Klasse Sonne der Inhalt der Protokollinhalt gesetzt wird dieser eine Art

+0

Sieht gut aus! Das Problem ist, dass ich nicht damit arbeiten kann. Zum Beispiel versuche ich in einer anderen Klasse 'func addContent (content: Content) {...}', aber Xcode zeigt an: 'Protokoll 'Inhalt' kann nur als generische Einschränkung verwendet werden, da es Selbst- oder assoziierte Typanforderungen hat ' – Mick

+0

Gleich um nur ein Array zu erstellen: 'var contents = [Content]()' – Mick

+1

@Mick Das liegt daran, dass ein 'Content' mit einem assoziierten Typ' String' einen komplett anderen Typ als 'Content' mit einem zugehörigen Typ' Int' hat . Es gibt keinen wirklichen Weg dahin, sie sind einfach nicht kompatibel. – Alexander

Verwandte Themen