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