Wie wird ein typgelöschter generischer Wrapper implementiert?
Ich muss einen Wrapper zum Löschen von Texten für meine eigene Struktur implementieren, der @ sehr ähnlich isSequenceOf
, GeneratorOf
, etc. Also habe ich angefangen, indem ich versucht habe, den Standard @ neu zu implementiereSequenceOf
mich selber
Ich habe gerade die Deklaration für @ kopiert und eingefüSequenceOf
, umbenannt inMySequenceOf
und füllte einige Stichwörter aus, um zu erhalten:
/// A type-erased sequence.
///
/// Forwards operations to an arbitrary underlying sequence with the
/// same `Element` type, hiding the specifics of the underlying
/// sequence type.
///
/// See also: `GeneratorOf<T>`.
struct MySequenceOf<T> : SequenceType {
/// Construct an instance whose `generate()` method forwards to
/// `makeUnderlyingGenerator`
init<G : GeneratorType where T == T>(_ makeUnderlyingGenerator: () -> G) {
fatalError("implement me")
}
/// Construct an instance whose `generate()` method forwards to
/// that of `base`.
init<S : SequenceType where T == T>(_ base: S) {
fatalError("implement me")
}
/// Return a *generator* over the elements of this *sequence*.
///
/// Complexity: O(1)
func generate() -> GeneratorOf<T> {
fatalError("implement me")
}
}
Ich erhalte den Compiler-Fehler: " Keiner der Typen im selben Typ bezieht sich auf einen generischen Parameter oder einen zugeordneten Typ ". Also gehe ich davon aus, dass die Xcode-generierte Deklaration vonSequenceOf
's "where T == T
"Einschränkung bedeutet wirklich"where G.Element == T
", was mir die folgende kompilierbare Struktur gibt:
struct MySequenceOf<T> : SequenceType {
init<G : GeneratorType where G.Element == T>(_ makeUnderlyingGenerator: () -> G) {
fatalError("implement me")
}
func generate() -> GeneratorOf<T> {
fatalError("implement me")
}
}
So jetzt, einfach genug, ich muss mich nur an @ haltmakeUnderlyingGenerator
vom Initialisierer aus und rufe es von @ aus agenerate()
:
struct MySequenceOf<T> : SequenceType {
let maker: ()->GeneratorOf<T>
init<G : GeneratorType where G.Element == T>(_ makeUnderlyingGenerator: () -> G) {
self.maker = { return makeUnderlyingGenerator() }
}
func generate() -> GeneratorOf<T> {
return self.maker()
}
}
Aber das gibt mir den Fehler: " 'G' kann nicht in 'GeneratorOf' konvertiert werden"
It does kompiliert, wenn ich eine Besetzung erzwinge:
struct MySequenceOf<T> : SequenceType {
let maker: ()->GeneratorOf<T>
init<G : GeneratorType where G.Element == T>(_ makeUnderlyingGenerator: () -> G) {
self.maker = { return makeUnderlyingGenerator() as GeneratorOf<T> }
}
func generate() -> GeneratorOf<T> {
return self.maker()
}
}
Aber dann stürzt es zur Laufzeit aus der dynamischen Besetzung.
Wie kann eine solche Typlöschung implementiert werden? Dies muss möglich sein, da die Swift-Standardbibliothek eine Reihe von Funktionen ausführt (SequenceOf, GeneratorOf, SinkOf).