Generators em Swift

agosto 1, 2016 12:00 pm Publicado por Deixe um comentário

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.

Mensagem do anunciante:

Conheça a Umbler, startup de Cloud Hosting por demanda feita para agências e desenvolvedores. Experimente grátis!

Source: IMasters

Categorizados em:

Este artigo foi escrito pormajor

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *