Pular para o conteúdo

Booleanos em Rust

Um booleano é o tipo mais simples que existe: ele só pode ser true (verdadeiro) ou false (falso). Em Rust ele se chama bool, e você vai usá-lo sempre que precisar tomar uma decisão no código.

fn main() {
let is_active = true;
let has_error: bool = false;
println!("ativo: {is_active}, erro: {has_error}");
}
▶ Experimente você mesmo

O Rust quase sempre deduz o bool sozinho a partir de true/false, então raramente você precisa escrever o tipo.

Em código de verdade, não é muito comum escrever true ou false diretamente. Eles costumam vir de uma comparação:

fn main() {
let age = 20;
let can_vote = age >= 18;
println!("Pode votar: {can_vote}");
}

Saída:

Pode votar: true
▶ Experimente você mesmo

A principal função de um bool é decidir qual ramo de um if vai rodar:

fn main() {
let is_raining = true;
if is_raining {
println!("Leve um guarda-chuva");
} else {
println!("Pode deixar em casa");
}
}

Vamos ver o if com calma na página If…Else. Isto aqui é só uma amostra de por que os booleanos são importantes.

Você conheceu && (e), || (ou) e ! (não) na página de Operadores. Falta saber mais uma coisa sobre eles: eles param antes quando a resposta já está decidida. Isso se chama avaliação em curto-circuito (short-circuit).

  • Em a && b, se a for false, o resultado inteiro só pode ser false, então o Rust nem olha para b.
  • Em a || b, se a for true, o resultado inteiro só pode ser true, então o Rust nem olha para b.

Isso é mais do que um truque de velocidade. Permite que o lado esquerdo proteja o lado direito:

fn main() {
let count = 0;
let total = 50;
// count é 0, então o Rust para depois de `count != 0` e nunca divide.
let big_average = count != 0 && total / count > 10;
println!("média alta: {big_average}");
let is_weekend = true;
let has_homework = true;
// is_weekend é true, então `!has_homework` nunca é verificado.
let can_relax = is_weekend || !has_homework;
println!("pode descansar: {can_relax}");
}

Saída:

média alta: false
pode descansar: true
▶ Experimente você mesmo

Dividir por zero faria o programa travar. Como count != 0 vem primeiro e é false, a divisão simplesmente nunca roda. Troque os dois lados de lugar (total / count > 10 && count != 0) e a divisão rodaria primeiro. Aqui o compilador até percebe e se recusa a compilar (“this operation will panic at runtime”, ou seja, esta operação vai causar um panic em tempo de execução); com um valor que só chega enquanto o programa está rodando, ele travaria. Então coloque a “verificação de segurança” do lado esquerdo.

Um brinquedo do parque de diversões deixa você entrar se você tiver pelo menos 120 cm de altura, ou se tiver pelo menos 8 anos e estiver com um adulto. Guarde uma altura de 115, uma idade de 9 e with_adult = true, e depois imprima se essa criança pode ir no brinquedo. Dica: use parênteses para agrupar a parte “idade e adulto”.

Ver solução
fn main() {
let height_cm = 115;
let age = 9;
let with_adult = true;
let tall_enough = height_cm >= 120;
let can_ride = tall_enough || (age >= 8 && with_adult);
println!("altura suficiente: {tall_enough}");
println!("pode ir: {can_ride}");
}

Saída:

altura suficiente: false
pode ir: true
▶ Experimente você mesmo

Um ano é bissexto se for divisível por 4 mas não por 100, ou se for divisível por 400. Calcule um booleano is_leap para 2024, imprima, e depois faça o mesmo para 1900. Dica: “divisível por 4” é year % 4 == 0, e você pode fazer shadowing de year e is_leap com um segundo let.

Ver solução
fn main() {
let year = 2024;
let is_leap = (year % 4 == 0 && year % 100 != 0) || year % 400 == 0;
println!("{year} é bissexto: {is_leap}");
let year = 1900;
let is_leap = (year % 4 == 0 && year % 100 != 0) || year % 400 == 0;
println!("{year} é bissexto: {is_leap}");
}

Saída:

2024 é bissexto: true
1900 é bissexto: false
▶ Experimente você mesmo
  • bool tem exatamente dois valores: true ou false.
  • Comparações (==, <, >=, …) produzem booleanos.
  • A condição de um if precisa ser um bool de verdade, sem conversões automáticas de números ou strings.
  • && e || fazem curto-circuito: pulam o lado direito assim que a resposta é conhecida, então coloque as verificações de segurança do lado esquerdo.

Teste o que aprendeu

1. Que tipo uma comparação como age >= 18 produz?

2. Em Rust, dá para usar um inteiro como 0 diretamente como condição de um if, como em algumas outras linguagens?

3. Em count != 0 && total / count > 10, o que acontece quando count é 0?

Pontuação: 0 / 3