Como é implementado um wrapper genérico apagado por tipo?
Preciso implementar um wrapper de exclusão de tipo para minha própria estrutura, muito semelhante aSequenceOf
, GeneratorOf
etc. Comecei tentando apenas reimplementar o padrãoSequenceOf
Eu mesmo.
Acabei de copiar e colar a declaração deSequenceOf
, renomeou-o paraMySequenceOf
e preencheu alguns stubs para obter:
/// 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")
}
}
Eu recebo o erro do compilador: "Nenhum tipo no mesmo tipo se refere a um parâmetro genérico ou tipo associado". Então, suponho que a declaração de código gerada pelo XcodeSequenceOf
é "where T == T
"restrição realmente significa"where G.Element == T
", que me fornece a seguinte estrutura compilável:
struct MySequenceOf<T> : SequenceType {
init<G : GeneratorType where G.Element == T>(_ makeUnderlyingGenerator: () -> G) {
fatalError("implement me")
}
func generate() -> GeneratorOf<T> {
fatalError("implement me")
}
}
Então agora, fácil, eu só preciso me agarrarmakeUnderlyingGenerator
do inicializador e invoque-o degenerate()
:
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()
}
}
mas isso me dá o erro: "'G' não pode ser convertido em 'GeneratorOf'"
istofaz compila se eu forçar um elenco:
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()
}
}
Mas então ele falha no tempo de execução do elenco dinâmico.
Então, como a eliminação de tipos como essa pode ser implementada? Isso deve ser possível, porque a biblioteca padrão do Swift faz muita coisa (SequenceOf, GeneratorOf, SinkOf).