por Leandro Cissoto
E chegamos ao nosso penúltimo artigo sobre Swift na parceria Quaddro + MacMagazine. Está acabando! Hoje vamos falar de Enums e Structs, e a diferença entre eles.
Lembramos que, para testar os conceitos aqui apresentados, recomendamos o uso do Xcode 6 ou superior. Se você não possui um Mac ou não quer instalar o Xcode, é possível utilizar uma ferramenta online que permite escrever em Swift diretamente pelo navegador.
Teoria
Se você vem de linguagens de programação como C e Objective-C, provavelmente você já deve ter ouvido falar de Enums e Structs. Porém, caso você esteja dando os seus primeiros passos, não se culpe caso nunca tenha visto nada a respeito: é muito comum ouvirmos falar antes de orientação a objetos e ficarmos exclusivamente presos a este paradigma antes de conhecermos tipos mais simples como Enums e Structs, que podem ser perfeitamente combinados com ele.
Enum
Enum (ou enumerado) é um tipo utilizado para definir uma lista de valores. Podemos fazer uma analogia com o mundo do desenvolvimento web e dizer que toda vez que usaríamos um dropdown de valores na web, podemos usar Enums na Swift.
Uma enumeração pode armazenar valores de qualquer tipo e os tipos destes valores podem ser diferentes para cada membro da enumeração. Para declarar um Enum, utilizamos a palavra enum
, seguida do nome que daremos ao nosso Enum. Dentro do bloco, utilizamos case
(sim, igual ao do switch
) para cada opção.
enum PontosCardeais { case Norte case Sul case Leste case Oeste } var direcao = PontosCardeais.Leste //Resultado: (Enum Value)
Perceba no exemplo acima que nosso enum
não é do tipo inteiro ou String. Os membros da enumeração PontosCardeais
são valores por si só e são do tipo PontosCardeais
. Isso faz com que trabalhar com enumeração seja seguro e mais explícito.
Podemos facilmente alterar o valor de um enum
depois que ele é declarado. Aproveitando o exemplo anterior, vamos alterar o valor de Leste
para Norte
. Exemplo:
direcao = .Norte
Também podemos declarar Enums que recebem diferentes tipos:
enum Tipos { case Str(String) case Num(Double) } var valor = Tipos.Str("hello") valor = .Num(1.0)
Os valores associados podem ser extraídos utilizando um switch
:
switch valor { case .Str(let val): print(val) case .Num(let val): print(val) }
Raw Values
Podemos utilizar Enums de maneira fortemente tipada, fazendo com que seus valores sejam sempre do mesmo tipo. Se utilizarmos inteiros, os valores são auto-incrementados se uma sequência não for informada. Não é possível declarar valores iguais.
Utilizamos .rawValue
para extrairmos o valor bruto informado dentro do Enum. Exemplo:
enum Semana : Int { case Domingo=78,Segunda,Terça,Quarta,Quinta,Sexta,Sábado } println("Semana Selecionada: \(Semana.Quinta.rawValue)") //Resultado: 82
Também podemos colocar funções dentro de Enums.
Struct
Uma Struct nos permite criar um tipo de dado estruturado que fornece um armazenamento de dados usando propriedades e funcionalidades através de métodos. É semelhante ao conceito de orientação a objetos, mas na verdade o conceito de Struct é muito mais simples do que uma classe, pois não permite herança.
Suas instâncias são sempre passadas por valor, diferentemente de classes, que são passadas por referência. Exemplo:
struct Pessoa{ var nome:String = "" var idade: Int = 0 var profissao: String? func trabalhar(){ let trabalho = profissao ?? "herdeiro" println("\(nome) está trabalhando de \(trabalho)") } } var pessoaX = Pessoa() pessoaX.nome = "Gusméia" pessoaX.idade = 35 pessoaX.trabalhar() pessoaX.profissao = "Programadora" pessoaX.trabalhar()
No exemplo anterior declaramos uma estrutura chamada Pessoa
, que recebe como propriedades nome
, idade
e profissão
, e pode executar uma funcionalidade (método) chamado trabalhar
. É um exemplo básico, mas já dá para mostrar como podemos estruturar nossos projetos utilizando essa poderosa opção.
Exercício guiado
Agora que já entendemos as diferenças entre Enum
e Struct
, vamos fazer um exercício guiado para consolidar ainda mais o que foi apresentado.
- Crie um novo documento chamado “struct-enums”.
- Vamos criar uma pequena lista de afazeres. Para isso, vamos criar uma Struct chamada “toDo”.
struct ToDo { }
- Agora, vamos pensar: o que uma lista de tarefas tem de propriedades? O que define uma lista de tarefas? Penso que, de maneira bem simplificada, o ideal para uma lista de tarefas seria ter título, conteúdo e responsável.
struct ToDo { var titulo:String = "" var conteudo: String = "" var responsavel: String = "" }
- Que tal colocarmos prioridade nessa lista? É uma boa oportunidade para utilizarmos o conceito de
enum
aninhado em umastruct
. Sim, é possível inserir umenum
dentro de umstruct
e vice-versa. 😉 Vamos criar esseenum
dizendo que a prioridade baixa será0
, a média será1
e a alta será2
.
struct ToDo { enum Prioridade: Int{ case Baixa = 0, Media, Alta } var titulo:String = "" var conteudo: String = "" var responsavel: String = "" var prioridade: Prioridade = Prioridade.Baixa }
- Agora que temos a nossa estrutura, podemos brincar de criarmos listas de tarefas.
var tarefasHoje = ToDo( titulo: "Terminar o site", conteudo: "Tenho que terminar o site do Gervásio", responsavel: "Leandro", prioridade: .Alta)
- Que tal utilizarmos um Array para declaramos nossas tarefas?
var todasTarefas: Array<ToDo> = [tarefasHoje, ToDo(titulo: "Dormir", conteudo: "Amanhã é folga", responsavel: "Leandro", prioridade: .Media), ToDo(titulo: "Fazer o jantar", conteudo: "Tenho que fazer o Jantar para a Ana", responsavel: "Leandro", prioridade: .Alta), ToDo(titulo: "Jogar algum game", conteudo: "Provavelmente Batman", responsavel: "Leandro", prioridade: .Baixa)
- Agora vou mostrar um método muito útil chamado Sort. Este método é utilizado para ordenar um Array de acordo com uma regra definida dentro de uma Closure (lembram delas?). Que tal ordenarmos a nossa lista de tarefas por ordem de prioridade? Faremos isso com apenas uma linha de código.
todasTarefas.sort({$0.prioridade.rawValue > $1.prioridade.rawValue})
Com apenas algumas alterações, podemos inverter esses valores e ordenarmos da maneira que quisermos.
· · ·
Com isso, concluímos o nosso exercício guiado sobre Structs e Enums. Recomendo bastante o estudo em cima desses dois carinhas, pois é muito comum nos depararmos com eles.
Desafio Blackjack ou 21
Vamos recriar a estrutura do famoso joguinho de cartas chamado Blackjack. Nele, o jogador vai tirando as cartas e elas não podem ultrapassar o valor 21. Quem chegar mais próximo ao valor sem ultrapassá-lo, vence.
As regras do jogo são:
- Cartas de 2 a 10 valem de 2 a 10;
- Cartas J, Q e K valem 10 pontos;
- A vale 1 ou 11.
Lembramos que no nosso GitHub você encontra os exercícios de todos os artigos, bem como as soluções dos desafios passados. No próximo e último artigo da nossa introdução à Swift, falaremos de Orientação a Objetos. Até lá!