Portuguese (Português) translation by David Batista (you can also view the original English article)
Você se surpreende que estou dedicando um tutorial para uma simples adição como a instrução guard
? Espero que você entenda melhor meu entusiasmo no final deste tutorial. Durante este tutorial, eu irei convencer você que o guard
não é uma adição redundante para a linguagem de programação Swift.
Minimizando a Complexidade
Condicionais é um componente fundamental para todas as linguagens de programação. Objective-C e Swift não são uma exceção para esta regra. Se você planeja desenvolver um aplicativo de qualquer complexidade, os condicionais estaram no seu caminho, não há como escapar deles.
Infelizmente, os condicionais muitas vezes são a causa da complexidade. Em particular, o encadeamento de condicionais pode elevar a dificuldade para encontrar erros, dificultar o entendimento do código e pode ser facilmente esquecido em casos extremos.
Para manter o minimo de instruções if
encadeadas, eu costumo usar o seguinte padrão em Objective-C.
- (void)fetchListOfCustomers:(NSArray *)customers { if (!self.reachable) return; if (!self.connected) return; if (!customers || ![customers count]) return; ... }
A ideia é garantir a saída o mais rápido possível. A instrução if
no exemplo representa um conjunto de requisitos que devem ser atendidos antes que o restante do método seja executado.
O exemplo acima se traduz para o equivalente a seguir um pouco mais complexo.
- (void)fetchListOfCustomers:(NSArray *)customers { if (self.reachable && self.connected) { if (customers && [customers count]) { ... } } }
Você vê o problema escondido neste exemplo? Nós já encadeamos dois níveis de profundidade sem ter feito nada de interessante.
É fácil de traduzir o padrão acima para o Swift. A sintaxe parece similar, mas devido ao customers
ser um opcional, precisamos desempacotar o argumento customers
antes de poder acessar seu valor.
func fetchListOfCustomers(customers: [Customer]?) { if !reachable { return } if !connected { return } if let customers = customers where customers.count > 0 { print(customers) } }
Saída Antecipada
O Swift 2 introduz a instrução guard
. Ela foi projetada especificamente para sair de um método ou função mais cedo. A instrução guard
é ideal para se livrar profundamente de condicionais encadeadas cujo único objetivo é validar um conjunto de requisitos. Dê uma olhada na atualização do exemplo em que substitui todas as instruções if
pela nova instrução guard
.
func fetchListOfCustomers(customers: [Customer]?) { guard !reachable else { return } guard !connected else { return } guard let customers = customers where customers.count > 0 else { return } print(customers) }
Há várias coisas dignas de nota. Vamos começar com a sintaxe.
Sintaxe
A palavra-chave guard
enfatiza que estamos validando um requisito. Estamos nos guardando contra algo. No exemplo, estamos verificando explicitamente se reachable
e connected
são iguais a true
. Se não forem, então nós saímos do método. O ponto é que a sintaxe é mais explicita sobre o requisitos do que a habitual instrução if
.
Saída
Note que uma instrução guard
sempre tem uma clausura else
. A clausura else
é executada se a condição da instrução guard
avaliada for igual a false
. Usar o guard
faz muito mais sentido quando você está validando requisitos.
Na clausura else
, você deve transferir o controle longe do âmbito em que a declaração guard
aparece. Usamos uma instrução return
no exemplo acima, mas você poderia, por exemplo, usar uma instrução continue
se você esta em um loop ou lançar uma exceção. Dê uma olhada no exemplo abaixo atualizado em que lançamos uma exceção na clausura else
. Note a palavra-chave throws
na declaração do método para indicar que fetchListOfCustomers(_:)
é um método de lançamento de exceção.
func fetchListOfCustomers(customers: [Customer]?) throws { guard !reachable else { throw APIError.APIErrorUnreachable } guard !connected else { throw APIError.APIErrorNotConnected } guard let customers = customers where customers.count > 0 else { throw APIError.APIErrorNoCustomers } ... }
Poderosa
Uma instrução guard
é tão poderosa quanto uma instrução if
. Você pode usar "optional bindings" e até mesmo o uso da clausura where
, introduzida no Swift 1.2, é permitida. Tenho certeza que você concorda que o exemplo é fácil de entender, eliminando o desnecessário encadeamento de condicionais.
Âmbito
Uma diferença importante com a instrução if
é o âmbito das variáveis e constantes que são atribuídas valores usando um "optional binding". No exemplo acima, a constante customers
teve um valor atribuído usando um "optional binding". A constante customers
é acessível dentro do âmbito em que a instrução guard
aparece. Este é um detalhe importante e uma das vantagens chave de usar o guard
.
Conclusão
Se você pensou que a guard
foi uma simples variação da instrução if
do Swift, então eu espero ter te convencido do contrário. Apesar da instrução if
continuar sendo sua ferrramenta de escolha na maioria das situações, a guard
tem um número de vantagens em determinadas situações. Isto é especialmente verdade se usada em combinação com manipulação de erro que também foi introduzido no Swift 2.
Seja o primeiro a saber sobre novas traduções–siga @tutsplus_pt no Twitter!
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Update me weeklyEnvato Tuts+ tutorials are translated into other languages by our community members—you can be involved too!
Translate this post