Wie geben Sie an, dass ein generischer Typparameter nur ein Protokoll sein kann (oder ein Protokoll, das diesem Protokoll entspricht), und keine Klasse, die diesem Protokoll entspricht?Swift Generics: Constrain Typ Parameter zu Protokoll
Zum Beispiel:
import Foundation
@objc protocol MyProtocol {
var name: String { get }
}
@objc protocol MySubProtocol: MyProtocol {
func foo()
}
class MyImplementation: MySubProtocol {
var name: String
init(name: String) {
self.name = name
}
func foo() {
print("Foo! Name: \(self.name)")
}
}
class InterfaceMaker<T: MyProtocol> {
init() {}
func makeInterface() -> NSXPCInterface {
return NSXPCInterface(with: T.self) // Cannot convert value of type 'T.Type' to expected argument type 'Protocol'
}
func getProxy() -> T? {
// Some magic in here involving `NSXPCConnection.remoteObjectProxy`
}
}
InterfaceMaker<MySubProtocol>().makeInterface() // No error, as expected
InterfaceMaker<MyImplementation>().makeInterface() // No error, but should not work!
Wie gebe ich, dass ein generischer Typ Parameter ein Protokoll enthalten sein sollte?
Ich möchte T
nur Protokolle konform MyProtocol
(wie MySubProtocol
) zu beschränken. Aber das Problem ist, ich weiß nicht, wie man verhindert, dass T eine Klasse ist (wie).
Ich versuchte bereits, T.self
zu beschränken (ich versuchte, where T.self : Protocol
zu verwenden, aber das verursachte den Fehler 'self' is not a member type of 'T'
).
Wie lege ich fest, dass T
ein Protokoll zu MyProtocol
, aber keine Klasse konform sein muss? Wenn das unmöglich ist, kann ich mindestens angeben, dass T irgendein Protokoll sein sollte? Es ist auch in Ordnung, wenn ich entweder eine class-only protocol machen muss.
Passing MySubProtocol
als nicht-generischer Parameter ist nicht, was ich suche, wie ich es auch für die InterfaceMaker.getProxy()
Funktion dieses Protokoll als eine Art in der Lage sein möchten zu verwenden. Darüber hinaus ist diese Funktion einfach MyProtocol
zurückgeben (mit anderen Worten, InterfaceMaker
nicht generisch zu sein) ist auch keine Option.
HINWEIS: Um vollständig klar zu sein, der Grund, warum ich T
brauchen ein Protokoll zu sein, ist, dass ich es NSXPCInterface.init(with:)
, passieren werde, die eine nimmt Protocol
(die durch SomeProtocol.self
wenn SomeProtocol
ist, erhalten werden kann @objc
) . Dies bedeutet, dass SomeProtocol.self.Type
ist oder entspricht
Wenn dies nicht möglich ist, geben Sie bitte eine vollständige Erklärung warum. Erwähnen Sie auch, ob dies in einer zukünftigen Swift-Version unterstützt werden könnte.
EDIT: Eine andere Art der Formulierung ist, dass T.self is AnyObject.Type
nie wahr sein sollte. Ich würde das lieber zur Kompilierzeit überprüfen als eine Laufzeitprüfung oder -überprüfung.
Warum interessieren Sie sich T beschränken sich nur auf Protokolle? Warum kann ich keine Oberklasse benutzen? – Alexander
@Alexander Was meinst du? Warum kannst du nicht eine Oberklasse für was verwenden? – Coder256
Was ist, wenn ich eine Klassenvererbungshierarchie verwende (zB 'Car',' SportsCar: Car', 'FamilyCar: Car') und keine Protokollhierarchie (zB' CarProtocol', 'SportsCarProtocol: CarProtocol',' FamilyCar: Protokoll "). Warum solltest du mich davon abhalten, 'Car' als Schnittstelle zu benutzen, und mich stattdessen zwingen,' CarProtocol' zu verwenden? – Alexander