Dando sequencia na série sobre Rust após um pequeno hiato vamos aprender hoje um pouco sobre como funcionam as variáveis em Rust, como declarar variáveis, constantes, mutabilidade, imutabilidade e etc..
Para começar vamos entender como declaramos uma simples variável em Rust, para isso vamos como sempre criar um novo programa usando o 'cargo new test_program', em seguida vamos abrir o arquivo `main.rs` do nosso programa e alterar a função main para que ela fique conforme o código abaixo:
fn main() {
let x: i8 = 2;
let name: &str = "philipe";
}
Veja no código acima temos a palavra chave 'let' que devemos usar sempre no inicio da declaração de uma variável em seguida temos o nome da variável, no caso temos duas variáveis uma chamada 'x' e outra 'name'. depois temos o ':' colocado bem ao lado do nome seguido por um espaço e o tipo da variável nesse caso uma variável do tipo 'i8' (numero inteiro que ocupa 8 bits na memória) e o tipo &str (uma string literal) por fim temos o sinal de igual seguido pelo valor de fato no caso 2 e "philipe" respectivamente.
O padrão de nomenclatura de variáveis/funções/métodos utilizado em Rust é o snake case, onde os mesmos devem ter seus nomes escritos em letras minúsculas, e em nomes compostos utilizamos o '_' para separarmos os nomes, veja o exemplo a seguir:
fn main() {
retirement_date = "never";
}
O compilador do Rust porém e bem esperto e muitas vezes consegue inferir qual é o tipo da variável que estamos declarando sendo assim podemos em casos como o visto acima omitir o tipo da variável no momento em que a estamos declarando como no código a seguir:
fn main() {
let x = 2;
let name = "philipe";
}
Mais para frente veremos casos onde o compilador em tempo de compilação não consegue adivinhar o tipo da variável e portanto deveremos declarar o tipo explicitamente.
Outra característica de Rust é que todas as variáveis são por padrão imutáveis, o que significa que uma vez que declaramos o valor de uma determinada variável não podemos mais alterar o valor da mesma durante a execução de um programa, como no exemplo a seguir que resultara em uma mensagem de erro do compilador.
fn main() {
let x = 1;
x = 2;
}
Como podemos observar na figura abaixo o compilador nos devolve uma mensagem de erro, mas reparem que ele nos diz exatamente qual é o problema: 'cannot assign twice to immutable variable', e nos aponta o trecho/linha onde o problema ocorreu e ainda por cima nos mostra uma maneira de resolver o problema 'help: make this binding mutable: `mut x`' realmente impressionante

.

As variáveis em Rust podem ser por padrão imutáveis mas podemos dizer para o compilador "ei eu quero que essa variável aqui possa ser alterada", para isso devemos acrescentar a palavra chave 'mut' logo antes do nome da variável como no código a seguir:
fn main() {
let mut x = 10;
x = 2;
}
E vejam só agora tudo funciona normalmente e o compilador não emite mais nenhuma mensagem de erro.

Vejam nenhuma mensagem de erro apenas avisos (warning) dizendo em resumo que estamos declarando uma variável e não estamos usando ela em lugar nenhum.
Um dos principais motivos pelo qual Rust faz com que as variáveis sejam imutáveis por padrão é a segurança de nos proporcionar a certeza de que durante a execução de um programa uma variável não poderá ter o seu valor alterado por qualquer método ou função o que torna os nossos programas menos suscetíveis a erros e mais fáceis de debugar uma vez que sabemos exatamente o valor de uma variável ao olharmos o lugar onde a mesma foi declarada
Mas o Rust é flexível e ainda nos da a opção de permitir que uma variável tenha seu valor alterado fazendo uso da palavra chave 'mut', o fato de termos de explicitar para o compilador que desejamos que uma variável possa ser alterada é ótimo pois isso tende a nos fazer refletir sobre se é mesmo necessário permitir que a variável seja alterada.
Ainda sobre variáveis em Rust podemos redefinir uma variável como no exemplo a seguir:
fn main() {
let age = 16;
let age = "15";
}
Vejam que não estamos alterando o valor da variável 'age' mas redefinindo a mesma, nesse caso podemos não só redefinir uma variável com um novo valor mas até mesmo com um tipo diferente como foi feito acima na primeira linha temos um valor do tipo inteiro 16 e na segunda um valor do tipo string literal "15", a esse tipo de situação em programação damos o nome de 'shadowing'.
O shadowing pode vir a ser util em alguma situações como no código abaixo:
fn main() {
let space = " ";
let space = space.len();
}
Vejam que no código acima declaramos uma variável chamada space do tipo string literal e em seguida queremos obter o tamanho da string, e guardá-lo numa variável de mesmo nome. Apesar do exemplo acima ser bem simples isso mostra como o uso de shadowing pode ser conveniente as vezes.
Para finalizar o post de hoje vamos falar sobre constantes. Em Rust declaramos uma constante de forma semelhante a uma variável porém ao invés de usarmos a palavra chave 'let' usamos a palavra chave 'const'
fn main() {
const PI: f64 = 3.14;
}
Vale dizer também que ao declararmos uma constante somos obrigados a explicitar qual o seu tipo de maneira que o código abaixo resultara em um erro.
fn main() {
const PI = 3.14;
}
Como podemos ver abaixo o compilador emite uma mensagem de erro e nos informa que devemos prover um tipo para a constante 'PI'.

Também não é possível fazer shadowing em uma constante se tentarmos executar o código a seguir obteremos um erro.
fn main() {
const PI: f64 = 3.14;
const PI: f64 = 3.2;
}
Na imagem abaixo vemos que o compilador emite um erro e nos avisa que uma constante não pode ser redefinida.

Também não podemos atribuir como valor de uma constante o retorno de uma função pois nesse caso o mesmo só poderia ser conhecido pelo nosso programa em tempo de execução, por tanto o código abaixo também resultara em um erro.
fn main() {
const SUM_NUMBERS: i8 = sum_numbers(2,1);
}
fn sum_numbers(n1: i8, n2: i8) -> i8 {
n1 + n2
}
Vejam o erro:

Uma constante diferentemente de uma variável pode ser declarada no escopo global como no código abaixo:
const PI: f64 = 3.14;
fn main() {
println!("pi = {}", PI);
}
Creio que vocês puderam notar que o padrão de nomenclatura de constates em Rust é o snake case porém todas as letras são maiúsculas.
Por fim fica claro que diferentemente de uma variável em Rust uma constante não é imutável por default ela é sempre imutável!
Não se preocupem quanto coisas como "quais são os tipos de dados primitivos em Rust" logo mais daremos sequencia nos posts e cobriremos esse tema.
Qualquer duvida ou problema com o post por favor postem um comentário abaixo, por favor comentários e criticas construtivas

.