freeCodeCamp/guide/portuguese/clojure/conditionals/index.md

7.7 KiB

title localeTitle
Clojure Conditionals Condicionais de Clojure

Você não vai chegar a lugar algum em um idioma, se tudo que você pode fazer é definir funções que imprimem coisas e fazem aritmética simples. Condicionais e lógicos são parte fundamental do código que faz coisas interessantes e úteis. Tente imaginar um mundo sem lógica em programas: você não seria capaz de coisas simples, como verificar se dois números são iguais!

Operadores lógicos

O Clojure, como a maioria das linguagens, possui 3 operadores lógicos: and , or e not . Essas funções usam booleanos ( true ou false ) como argumentos e retornam booleanos com base no que esses booleanos são. Como tudo em um Lisp, esses operadores usam a notação de prefixo, o que significa que eles podem parecer estranhos para você.

(and true false) 
 ; => false 
 (and true true) 
 ; => true 
 (or false false) 
 ; => false 
 (or true false) 
 ; => true 
 (not true) 
 ; => false 
 (not false) 
 ; => true 

:rocket: IDEOne isso!

E se

if permite executar código baseado em se um booleano é true ou false . if no Clojure parece bastante estranho, não porque ele usa notação de prefixo, mas porque não há outra palavra-chave. Se a condição for verdadeira, ela avalia a primeira expressão. Se é falso, executa o segundo.

(if (= (+ 2 2) 4) 
  (println "Maths works!") ; this gets evaluated if 2 + 2 = 4 
  (println "UH OH"))       ; this gets evaluated if 2 + 2 != 4 
 ; => Maths works! 
 ;    nil 

Isso apresenta um problema: e se quisermos fazer várias coisas?

(if (= (+ 2 2) 4) 
  (println "Maths works!") 
  (println "Maths still works!") 
  (println "UH OH")) 
 ; => CompilerException java.lang.RuntimeException: Too many arguments to if 

Felizmente, temos a do a função de resolver este problema. do avalia múltiplas expressões, um após o outro.

(if (= (+ 2 2) 4) 
  (do                               ; all of this gets evaluated if 2 + 2 = 4 
    (println "Maths works!") 
    (println "Maths still works!")) 
  (println "UH OH")) 
 ; => Maths works! 
 ;    Maths still works! 
 ;    nil 

Nota: já que if é, em si, uma expressão, não há necessidade de um operador ternário como em muitas linguagens semelhantes a C.

var doesMathsWork = 2 + 2 === 4 ? "Maths works!" : "UH OH"; 
 console.log(doesMathsWork); 
 // => Maths works! 

Agora que você viu como funciona, não parece tão estranho, certo? Isso é muito mais fácil de ler e entender (ignorando a falta da palavra else ):

(def does-maths-work (if (= (+ 2 2) 4) "Maths works!" "UH OH")) 
 (println does-maths-work) 
 ; => Maths works! 
 ;    nil 

:rocket: IDEOne isso!

Alternativas para se

O Clojure também possui algumas macros que se comportam de forma semelhante a if , e às vezes podem ser mais concisas.

if-not é talvez o exemplo mais simples - é if invertido. Esses dois pedaços de código são exatamente os mesmos:

(def does-maths-work (if (not (= (+ 2 2) 4)) "UH OH" "Maths works!")) 
 (def does-maths-work (if-not (= (+ 2 2) 4) "UH OH" "Maths works!")) 

A primeira expressão é avaliada se for falsa e a segunda é avaliada se for verdadeira. Observe que o uso if-not evita nidificação nossa condição dentro not , o que pode ajudar a tornar o nosso código mais fácil de entender.

when é outra macro útil. Esses dois pedaços de código também são os mesmos:

(if (= (+ 2 2) 4) (do (println "Maths works!") (println "Hooray!"))) 
 (when (= (+ 2 2) 4) (println "Maths works!") (println "Hooray!")) 

:rocket: IDEOne isso!

Nota: Não há when/else . when executa se a condição é verdadeira.

cond permite combinar muitas condições em uma única expressão. Ele usa uma sequência de pares de expressões e expressões lógicas e avalia cada expressão lógica em ordem. Quando encontra uma expressão lógica que avalia como true , avalia a segunda expressão do par. Depois disso, nenhuma outra expressão é avaliada. Esse comportamento é como lógica de curto-circuito no Javascript.

(cond (= 0 1) "I'm paired with a false expression and I don't evalute.." 
      (= 1 1) "I'm the first expression paired with a true expression!" 
      (= 2 2) "I don't evalute even though I'm also paired with true ;_;" 
      :else   "I evaluate if no other boolean expressions evaluate to true") 
 ; => "I'm the first expression paired with a true expression!" 

:rocket: IDEOne isso!

A palavra-chave :else pode ser usada no lugar de uma expressão lógica no último par de expressões em cond . Isso significa que a expressão correspondente deve ser avaliada se todas as outras expressões booleanas forem avaliadas como falsas. É o mesmo que colocar a true como a última expressão booleana.

Formas Especiais e Avaliação

Você deve ter notado que as regras de avaliação de expressões condicionais são um pouco diferentes de outras expressões. A expressão condicional faz parte de um grupo de expressões chamado formulários especiais . Isso significa que eles não seguem as regras normais de avaliação do Clojure.

Como você sabe agora, uma expressão condicional avalia apenas a subexpressão que corresponde ao resultado booleano. Isso significa que o código inválido em uma expressão condicional não será avaliado em alguns casos. Considere as duas expressões if abaixo. Embora (+ 1 "failure") seja uma expressão inválida, o Clojure apenas gera uma exceção quando a condição é false .

(if true "sucess" (+ 1 "failure")) 
 ; => "sucess" 
 (if false "sucess" (+ 1 "failure")) 
 ; => ClassCastException java.lang.String cannot be cast to java.lang.Number ... 

:rocket: IDEOne isso!

Compare isso com o comportamento do my-if definido abaixo:

(defn my-if [condition true-case false-case] 
  (if condition true-case false-case)) 
 
 (my-if true "sucess" (+ 1 "failure")) 
 ; => ClassCastException java.lang.String cannot be cast to java.lang.Number ... 

:rocket: IDEOne isso!

my-if é uma função com regras de avaliação normais, portanto todas as subexpressões devem ser avaliadas antes de poderem ser avaliadas.

O Clojure tem muitas macros úteis como essas para todos os tipos de tarefas. Tente dar uma olhada na documentação do Clojure e veja se você pode encontrar mais!

| :point_left: Anterior | :book: Casa :book: | Próximo :point_right: |
| Resumo | Índice | Condicionais |