Guarda pode melhorar a clareza
Quando você usa o guarda, você tem uma expectativa muito maior de que o guarda seja bem - sucedido e é um pouco importante que, se não for bem-sucedido, você queira sair do escopo mais cedo . Como você guarda para ver se existe um arquivo / imagem, se uma matriz é Vazia ou não.
func icon() -> UIImage {
guard let image = UIImage(named: "Photo") else {
return UIImage(named: "Default")! //This is your fallback
}
return image //-----------------you're always expecting/hoping this to happen
}
Se você escrever o código acima com if-let, ele transmite ao desenvolvedor de leitura que é mais do que 50-50. Mas se você usa o guarda, adiciona clareza ao seu código e isso implica que eu espero que funcione 95% das vezes ... se alguma vez falhou, não sei por que; é muito improvável ... mas use essa imagem padrão ou apenas afirme com uma mensagem significativa descrevendo o que deu errado!
Evite guard
s quando criarem efeitos colaterais, as proteções devem ser usadas como um fluxo natural . Evite guardas quando as else
cláusulas introduzirem efeitos colaterais. Os guardas estabelecem condições necessárias para que o código seja executado corretamente, oferecendo saída antecipada
Ao executar um cálculo significativo na ramificação positiva, refatorar de if
para uma guard
instrução e retornar o valor de fallback na else
cláusula
De: livro Swift Style de Erica Sadun
Além disso, como resultado das sugestões acima e do código limpo, é mais provável que você queira / precise adicionar asserções a declarações de guarda com falha , isso apenas melhora a legibilidade e deixa claro para outros desenvolvedores o que você estava esperando.
guard let image = UIImage(named: selectedImageName) else { // YESSSSSS
assertionFailure("Missing \(selectedImageName) asset")
return
}
guard let image = UIImage(named: selectedImageName) else { // NOOOOOOO
return
}
De: livro Swift Style de Erica Sadun + algumas modificações
(você não usará declarações / condições prévias para if-let
s. Simplesmente não parece certo)
Usar guardas também ajuda a melhorar a clareza, evitando a pirâmide da desgraça. Veja a resposta de Nitin .
Guard cria uma nova variável
Há uma diferença importante que acredito que ninguém explicou bem.
Ambos guard let
e if let
desembrulhar a variável no entanto
Com guard let
você, você está criando uma nova variável que existirá fora da else
instrução.
Como if let
você não está criando nenhuma nova variável - após a instrução else, você só insere o bloco de código se o opcional for nulo. A variável recém-criada existe apenas dentro do bloco de código não depois!
guard let:
func someFunc(blog: String?) {
guard let blogName = blog else {
print("some ErrorMessage")
print(blogName) // will create an error Because blogName isn't defined yet
return
}
print(blogName) // You can access it here ie AFTER the guard statement!!
//And if I decided to do 'another' guard let with the same name ie 'blogName' then I would create an error!
guard let blogName = blog else { // errorLine: Definition Conflicts with previous value.
print(" Some errorMessage")
return
}
print(blogName)
}
if-let:
func someFunc(blog: String?) {
if let blogName1 = blog {
print(blogName1) // You can only access it inside the code block. Outside code block it doesn't exist!
}
if let blogName1 = blog { // No Error at this line! Because blogName only exists inside the code block ie {}
print(blogName1)
}
}
Para obter mais informações if let
, consulte: Por que a redeclaração da ligação opcional não cria um erro?
Guarda requer escopo saindo
(Também mencionado na resposta de Rob Napier):
Você DEVE ter guard
definido dentro de uma função. Seu principal objetivo é abortar / retornar / sair do escopo, se uma condição não for atendida:
var str : String?
guard let blogName1 = str else {
print("some error")
return // Error: Return invalid outside of a func
}
print (blogName1)
Para if let
você não precisa tê-lo em nenhuma função:
var str : String?
if let blogName1 = str {
print(blogName1) // You don't get any errors!
}
guard
vs if
Pena de notar que é mais apropriado para ver esta questão como guard let
vs if let
e guard
vs if
.
Um autônomo if
não desembrulha, nem um autônomo guard
. Veja o exemplo abaixo. Não sai mais cedo se um valor é nil
. Não há valores opcionais. Ele sai cedo se uma condição não for atendida.
let array = ["a", "b", "c"]
func subscript(at index: Int) -> String?{
guard index > 0, index < array.count else { return nil} // exit early with bad index
return array[index]
}
if let
quando onon-nil
caso for válido. Useguard
quando onil
caso representa algum tipo de erro.