Tô há um tempão sem escrever! Mas estou com algumas novidades, atualmente estou trabalhando com mobile, no Elo7 e claro não desisti do funcional, ando estudando haskell de uma forma um pouco mais compromissada, todas as quintas-feiras estou participando de um dojo de haskell, quem quiser, só mandar um email no abner.terribili@gmail.com ou se caso estiver muito longe e queira participar de longe, aceitamos pull requests em wando-hs :)
Para estrear o mobile aqui no Hackeando, que tal conhecermos o poder do Enum no Swift?
O que é Enum?
Enum, no Swift, nada mais é do que a definição de um tipo para um grupo de valores que têm alguma relação.Abstrato né?
Imagine que você precisa filtrar uma lista, é um exemplo meio recorrente no meu dia a dia, por isso o escolhi. Então, temos uma lista de jogos, e desejo filtrar por plataforma, o enum em Java, seria algo do tipo:
enum GameFilter { PS3("playstation3"), PS4("playstation4"), XBOX360("xbox360"), XBOX_ONE("xboxOne"); final String tag; GameFilter(String tag) { this.tag = tag; } @Override public String toString() { return tag; } }
O tag aí serve para podermos pegar o valor que será aplicado no momento de filtro, ou seja, para montar a url:
www.lojadejogos.com/jogos?plataforma=playstation3
Podemos ver que, usando Java, precisamos de uma pequena field auxiliar para guardarmos o valor da tag. Vamos dar uma olhadinha no GameFilter construído em Swift:
enum GameFilter: String { case PS3 = "playstation3" case PS4 = "playstation4" case XBOX360 = "xbox360" case XBOX_ONE = "xboxOne" func description() -> String {return self.rawValue} }
São quase iguais né? Com a diferença que ao invés de uma field auxiliar para armazenar o valor da tag, nós baseamos nosso enum em String.
Isso é muito chato e básico!
Vamos fazer algo mais legal, imagina que você quer ter um pouco mais de segurança com o que você trabalha (se costuma programar, já deve ter tomado um
NullPointerException
na cara),
semântica e é hipster, sendo assim decidiu implementar um Optional na mão, isso tem fins didáticos, pois no Swift já temos uso extensivo de Optional.Então temos nosso enum:
enum Optional<T> { case None case Some(T) init(_ value: T) { self = .Some(value) } init() { self = .None } func getOrElse() -> Any { switch self { case .Some(let value): return value default: return Optional.None } } }
Na linha
enum Optional<T> {..}
nós definimos o nome do Enum, e declaramos um tipo genérico que será usado para inferir o tipo.Com isso nós implementamos dois construtores, um que recebe um valor qualquer
init(_ value: T) {self = .Some(value)}
e
outro que não recebe nenhum argumento: init() {self = .None}
, fica meio maluco esse bind self=**
, mas entenda, estamos
atribuindo o valor da instância de acordo com o construtor que é usado. :)E por fim, definimos um método que devolve qualquer coisa (
Any
), o objeto que está envelopado ou um
Optional.None, e que faz a validação pra gente a respeito da instância que está chamando o getOrElse()
.Para usarmos nosso Optional é simples:
let none = Optional() none.getOrElse() //-> () let some = Optional(10.0) some.getOrElse() //-> 10
Podemos ver que o construtor vazio devolve None, ou seja, nada, já o construtor que tem parametro, devolve o valor que foi passado, e olha que legal o Generics funcionando no Swift!
E aí, deu pra sentir a força do
enum
no Swift? E da pra fazer MUITO mais. Isso é só o básico :)Só pra finalizar, se você já deu uma olhadinha de leve em Swift, com certeza o conceito de Optional não passou batido, pra nossa implementação ficar bacanuda, o que acham de implementarmos o sufixo para fazer unwrap do valor?
postfix operator *? {} postfix func *? <T>(value: Optional<T>) -> Any { return value.getOrElse() }
O código não é tão claro, mas basicamente estamos definindo um operador, do tipo sufixo, ou seja, que é utilizado no fim da expressão. Algo como:
Optional("xablau")*? //-> "xablau"
E por hoje é só galera, se rolar alguma dúvida ou sugestão, só comentar abaixo ou me enviar um email
Abraços