Pular para o conteúdo

Sintaxe do Rust

Agora que você já consegue rodar Rust, vamos com calma ver o que cada parte de um programa realmente significa. Vamos usar o menor exemplo possível e desmontá-lo peça por peça.

fn main() {
println!("Olá, mundo!");
}

Saída:

Olá, mundo!
▶ Experimente você mesmo
fn main() {
// seu código roda aqui
}

Todo programa em Rust começa em uma função chamada main. Quando você roda o programa, o Rust procura a main e executa o código que está dentro dela.

  • fn é a palavra-chave para definir uma função (um bloco de código com nome).
  • main é o nome da função. Esse nome é especial: é o ponto de entrada do programa.
  • () guarda as entradas da função (aqui está vazio, porque a main não recebe nenhuma).
  • { } as chaves envolvem o corpo, ou seja, o código que pertence à função.

Dentro do corpo, cada comando normalmente é uma instrução (statement), e as instruções terminam com ponto e vírgula ;:

fn main() {
let x = 5;
let y = 10;
println!("{}", x + y);
}

Saída:

15
▶ Experimente você mesmo

Esquecer um ponto e vírgula onde ele é esperado é um dos erros mais comuns de quem está começando, e o compilador vai apontar exatamente o lugar.

O código Rust é feito de dois tipos de peças, e a diferença importa mais em Rust do que na maioria das linguagens:

  • Uma instrução (statement) faz algo, mas não devolve nenhum valor. let x = 5; é uma instrução.
  • Uma expressão (expression) produz um valor. 5, x + 1 e x * 2 são todas expressões.

Agora vem a parte que surpreende: um bloco de código entre chaves { } também é uma expressão. O valor dele é a última linha, escrita sem ponto e vírgula:

fn main() {
let x = 5;
let y = {
let doubled = x * 2; // uma instrução dentro do bloco
doubled + 1 // sem ponto e vírgula: este é o valor do bloco
};
println!("y vale {y}");
}

Saída:

y vale 11
▶ Experimente você mesmo

O bloco executa suas instruções e depois devolve doubled + 1, que é 11, e esse valor vai para y. Repare no ponto e vírgula depois da } de fechamento: a linha inteira let y = ...; continua sendo uma instrução.

Se você colocar um ponto e vírgula depois de doubled + 1, ele deixa de ser o valor do bloco. O bloco passa a devolver “nada” (o Rust escreve isso como ()), e o println! não consegue imprimir isso, então o código não compila. Essa regra de “sem ponto e vírgula na última linha” é exatamente como as funções retornam valores. Você vai ver isso de novo na página de Funções e com o if como expressão.

Olhe com atenção para o println!: esse ponto de exclamação não é erro de digitação. O ! indica que é uma macro, e não uma função comum.

Você ainda não precisa entender macros a fundo. Só guarde isto: quando aparecer um !, é uma macro. Por enquanto, a única que você vai usar é o println!, para imprimir texto.

fn main() {
println!("Isto é uma chamada de macro");
}

Dentro do println!, as chaves {} são marcadores (placeholders) que são preenchidos com os valores que você passa depois do texto:

fn main() {
let name = "Ferris";
let age = 10;
println!("{} tem {} anos", name, age);
}

Saída:

Ferris tem 10 anos
▶ Experimente você mesmo

Você também pode colocar o nome da variável direto dentro das chaves, o que costuma deixar o código mais limpo:

println!("{name} tem {age} anos");

O Rust não liga para a indentação como o Python liga. Ele usa as chaves { } para saber onde cada bloco começa e termina. A indentação serve só para pessoas lerem o código com mais facilidade.

Mesmo assim, a comunidade tem um estilo padrão, e o Rust vem com uma ferramenta que aplica esse estilo automaticamente:

Terminal window
cargo fmt

Rodar cargo fmt reformata seu código no estilo oficial. Crie o hábito de usar.

Você pode deixar anotações no código que o Rust ignora. Elas se chamam comentários e começam com //:

fn main() {
// Isto é um comentário, o Rust pula esta linha
println!("Olá!"); // comentários também podem ficar no fim de uma linha
}

Vamos falar de comentários com mais detalhes na próxima página.

Crie duas variáveis, a = 7 e b = 3, e imprima 7 + 3 = 10. Deixe o Rust fazer a soma. Dica: um println! pode ter vários marcadores {}, preenchidos em ordem pelos valores que vêm depois do texto.

Ver solução
fn main() {
let a = 7;
let b = 3;
println!("{} + {} = {}", a, b, a + b);
}

Saída:

7 + 3 = 10
▶ Experimente você mesmo

Uma loja vende 3 itens a 4 cada um, mais 2 de frete. Calcule total com um bloco { }: dentro dele, crie um subtotal e depois devolva subtotal + 2. Imprima Total: 14. Dica: a última linha do bloco não pode ter ponto e vírgula.

Ver solução
fn main() {
let price = 4;
let quantity = 3;
let total = {
let subtotal = price * quantity;
subtotal + 2 // frete
};
println!("Total: {total}");
}

Saída:

Total: 14
▶ Experimente você mesmo
  • Todo programa começa pela função main.
  • O código fica dentro de chaves { }, e a maioria das instruções termina com ;.
  • Instruções fazem algo; expressões produzem um valor. A última linha de um bloco, sem ;, é o valor dele.
  • Um ! (como em println!) indica que é uma macro.
  • As {} dentro do println! são marcadores preenchidos pelos valores que você passa.
  • A indentação serve para facilitar a leitura. Rode cargo fmt para formatar automaticamente.

Teste o que aprendeu

1. O que a função main tem de especial em um programa Rust?

2. O que significa o ! depois de println?

3. Qual é o valor de y depois de let y = { let a = 2; a + 1 };?

Pontuação: 0 / 3