Generators em Swift
Por que temos que entender o que é Generator? Essa pergunta não abrange só o tema deste artigo, mas também os diversos tipos de objetos que são utilizados pela sua aplicação.
A primeira pergunta que vem à cabeça é por que temos que entender o que é Generator?
Essa pergunta não abrange somente o tema deste artigo, mas também os diversos tipos de objetos que são utilizados pela sua aplicação. Em uma resposta mais geral: quanto mais você entende o que ocorre por trás das “frameworks/APIs/SDKs…” que você utiliza em sua aplicação, mais insumo você tem para poder realizar otimizações e tomar decisões importantes que irão impactar diretamente na qualidade do código do seu app.
E em uma resposta mais específica temos: basicamente esse tipo é uma das bases de todas as “Collections e Sequences” que existem no Swift. E você irá utilizá-lo para construir futuramente suas próprias sequências e coleções, ou pelo menos entender como elas funcionam.
O Generator
É um protocolo que é utilizado para um simples propósito: gerar elementos e objetos finitos, como mostra o exemplo abaixo:
public protocol GeneratorType {
associatedtype Element
public mutating func next() -> Self.Element?
}
O protocolo GeneratorType é bem simples, contém apenas duas implementações. O next(), que é utilizado como provedor dos elementos, e o “Element”, que é usado para definir o tipo gerado pela nossa implementação.
Podemos implementá-lo da seguinte maneira:
/ Coolest class ever
class CoolGenerator: GeneratorType {
typealias Element = String
let collCount: Int
private var count: Int = 0
init( collCount: Int ) {
self.collCount = collCount
}
//Generates cool string
func next() -> Element? {
count += 1
if count <= collCount {
return "?"
}
return nil
}
}
Bem, nesse momento você deve estar se perguntando: “Para que diacho eu vou utilizar isso?”.
Utilizando o protocolo de GeneratorType você já possui a vantagem de não precisar saber o que ocorre dentro da implementação, apenas que ela vai te retornar alguma coisa do tipo já definido toda vez que você chamar o método next() e que em algum momento o gerador irá te enviar “nil” para te avisar que a geração chegou ao fim. E o mais importante, ao criar um Generator o nome (classe/struct) deve passar a informação do que está por ser gerado. No caso abaixo usamos StringPrefixGenerator, que sua funcionalidade é criar prefixos a partir de strings.
Segue um exemplo para Generators:
/// Prefix Class Generator
class StringPrefixGenerator: GeneratorType {
typealias Element = String
let string: String
var offset: String.Index
init(string:String) {
self.string = string
self.offset = string.startIndex
}
/**
Get always the next letter at the sentence and return new prefix based on previous one
- returns: returns new prefix
*/
func next() -> Element? {
guard offset < string.endIndex else {
return nil
}
offset = offset.successor()
return string[ string.startIndex..<offset ]
}
}
let prefixGenerator = StringPrefixGenerator(string: "Douglas Mendes Barreto")
prefixGenerator.next() //print D
prefixGenerator.next() //print Do
prefixGenerator.next() //print Dou
Obs: É importante saber que apesar de podermos fazer com que os nossos Generators sejam infinitos, esse tipo de comportamento não é esperado para quem for utilizar nossa implementação, e é por isso que o tipo de retorno do método next() é um optional “Element?” para informar, utilizando “nil”, que a geração chegou ao fim.
Apesar de simples esse protocolo é essencial para podermos estudar 0 SequenceType, que será o tema do nosso próximo artigo. Ficou alguma dúvida ou tem alguma contribuição? Deixe abaixo!
Até mais!
É desenvolvedor iOS e tem interesse em fazer parte de um time ágil de verdade? Acesse aqui.







