Aprendendo Rust: 06 - Controles de fluxo
Tags: rust, tutorial
Published: 2020-08-07 10:59:00

E aee jovens, tudo bem com vocês?

Nesta postagem iremos entender sobre como controlar o fluxo da nossa aplicação, usar condicionais e criar estruturas de repetição.

Então, lets'go!!!

## If / Else

E se quiséssemos criar por exemplo um sistema para uma escola, onde se um aluno tirou uma nota igual ou maior que 7 o sistema apresentasse uma mensagem _"Aluno aprovado!"_ e se fosse menor que 7 _"Aluno reprovado!"_, como seria feito?

Vamos criar um sistema que imprima essa mensagem, no terminal vamos criar o projeto e executar o VS Code com os comandos abaixo:

```bash
cargo new control_flow
cd control_flow
code .
```
Vamos substituir o conteúdo do arquivo _main.rs_:

```rust
fn  main() {
    let number = 7.5;

	if number >= 7.0 {
		println!("Aluno aprovado!");
	} else {
		println!("Aluno reprovado!");
	}
}
```

A palavra reservada `if` verifica uma condição, se a expressão for verdadeira será executado o que temos dentro das chaves `{}`, neste exemplo verificamos se o numero for maior do que 7.0 e se for imprima o texto _"Aluno aprovado!"_. Enquanto, a palavra reservada `else` será executada caso a condição do `if` for falsa, então se alterarmos o valor da variável `number` pra 4.5, será apresentado na tela _"Aluno reprovado!"_.

Ao executarmos o programa com o comando `cargo run` teremos uma saída parecida com:

```bash
Compiling control_flow v0.1.0 (/home/pehdepano/dev/workspace/rust/learning_rust/06 - Control Flow/control_flow)
  Finished dev [unoptimized + debuginfo] target(s) in 0.36s
    Running `target/debug/control_flow`
Aluno aprovado!
```

Podemos querer fazer mais de uma condição, vamos alterar o nosso exemplo com o código abaixo:

```rust
fn  main() {
	let number = 5.5;

	if number < 5.0 {
		println!("Aluno aprovado!");
	} else  if number >= 5.0  && number < 7.0 {
		println!("Aluno de recuperação!");
	} else {
		println!("Aluno reprovado!");
	}
}
```

Neste caso, fazemos uma validação se o numero é menor do que 5, se for o aluno reprovou, se o numero estiver entre 5.0 e 6.999... o aluno está de recuperação, e se não atender a nenhuma dessas duas validações quer dizer que o aluno foi aprovado.

Na condição `number >=  5.0  && number <  7.0` usamos o denominador `&&` que fará uma validação se as duas expressões são verdadeiras, leriamos essa linha assim _"Se o numero for maior ou igual a 5 __E__ se o numero for menos do que 7"_.

Ao executarmos o programa com o comando `cargo run` teremos uma saída parecida com:

```bash
Compiling control_flow v0.1.0 (/home/pehdepano/dev/workspace/rust/learning_rust/06 - Control Flow/control_flow)
  Finished dev [unoptimized + debuginfo] target(s) in 0.20s
    Running `target/debug/control_flow`
Aluno de recuperação!
```

Também temos como usar o __ou__ na expressão com o denominador `||`:

```rust
if age > 18 || money > 50.0 {
	println!("Eu posso comprar");
}
```

Neste caso seria validado se a idade é maior do que 18 __OU__ o dinheiro é maior do que 50.0, se qualquer uma das informações for verdadeira será apresentado na tela `Eu posso comprar`.

Como na maioria das linguagens _Rust_ tem os seguintes operadores alem do `&&` e do `||`:

`==` -> operador de igualdade _5 == 5_. 
`!=` -> operador de desigualdade _5 != 6_.
`<` -> operador menor _5 < 6_. 
`<=` -> operador menor ou igual _6 <= 6_. 
`>` -> operador maior _6 > 5_. 
`>=` -> operador maior ou igual _5 >= 5_. 
`!` -> negação _!(5 >6)_.


## Loop

Em muitas ocasiões vamos precisar executar uma determinada instrução inúmeras vezes, para isso temos algumas opções, a primeira que veremos é a palavra reservada `loop`.

Vamos criar um novo programa para exemplificar, no terminal vamos criar o projeto e executar o VS Code com os comandos abaixo:

```bash
cargo new loops
cd loops
code .
```
Vamos substituir o conteúdo do arquivo _main.rs_:

```rust
fn  main() {
	let  mut number = 0;

	loop {
		if number == 10 {
			break;
		}
		print!("{} - ", number);
		number += 1;
	}
}
```

Tudo o que estiver dentro das chaves do `loop` será executado até que o numero seja igual a 10. O comando `break` irá parar a execução do `loop`.

Na linha `number += 1;` o `+=` é um incremento de 1 dentro da variável `number` poderíamos ter feito assim `number = number + 1;` que no final seria a mesma coisa, mas para manter um código menor, e que eu considero mais limpo sempre vou utilizar da maneira que coloquei no exemplo. Além do `+=`, temos as opções:

`-= valor;` -> `number = number - valor`.
`*= valor;` -> `number = number * valor`.
`/= valor;` -> `number = number / valor`.

Ao executarmos o programa com o comando `cargo run` eremos uma saída parecida com:

```bash
Compiling loops v0.1.0 (/home/pehdepano/dev/workspace/rust/learning_rust/06 - Control Flow/loops)
  Finished dev [unoptimized + debuginfo] target(s) in 0.20s
    Running `target/debug/loops`
0 - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10
```

Temos que tomar muito cuidado ao usar `loop` pois se não colocarmos de alguma forma o comando de parar a execução, entraremos em um _loop_ infinito, e o sistema ficará executando eternamente.

## While

Além do `loop` temos a palavra reservada `while` que também executará um bloco _n_ vezes. Vamos ao exemplo:

```rust
while number <=  10 {
	print!("{} - ", number);
	number +=  1;
}
```

A saída desse código será igual a que fizemos com o comando `loop`. E da mesma forma é preciso um certo cuidado, pois podemos entrar em um _loop_ infinito dependendo de como realizamos a construção do nosso código.

## For

Temos mais uma opção para realizarmos repetições em _Rust_ a palavra reservada `for`:

```rust
let a = [10, 20, 30, 40, 50];
for element in a.iter() {
	println!("the value is: {}", element);
}
```

`let a = [10, 20, 30, 40, 50];` -> criamos um _vetor_ com 5 posições.

`for element in a.iter()` -> estamos iterando o _vetor_ chamado _a_, ou seja estamos percorrendo item a item do _vetor_.

`println!("the value is: {}", element);` -> para cada iteração será impresso o valor do item atual.


Ao executarmos esse projeto com o comando `cargo run` teremos uma saída parecida com:

```bash
Compiling loops v0.1.0 (/home/pehdepano/dev/workspace/rust/learning_rust/06 - Control Flow/loops)
  Finished dev [unoptimized + debuginfo] target(s) in 0.22s
    Running `target/debug/loops`
the value is: 10
the value is: 20
the value is: 30
the value is: 40
the value is: 50
```

Para conseguirmos imprimir esse mesmo vetor em ordem inversa, só mudaríamos a linha `for element in a.iter() {` para `for element in a.iter().rev() {`.

Vou adicionar o fonte desta postagem no _Github_, segue o link: [Aprendendo Rust](https://github.com/RichardJd/aprendendo-rust)

Quaisquer dúvidas ou sugestões para que eu melhore nas postagens deixe um comentário, e continue acompanhando os próximos posts.

# Referencias

[O livro de Rust](https://doc.rust-lang.org/book/)

[Tour of Rust](https://tourofrust.com/)

[CodeShow](https://www.twitch.tv/codeshow)