Macros são mais poderosos do que funções porque se expandem para produzir mais código do que o código que você escreveu manualmente. Por exemplo, uma assinatura de função deve declarar o número e o tipo de parâmetros que a função possui. Macros, por outro lado, podem receber um número variável de parâmetros: podemos chamar `println!("hello")` com um argumento ou `println!("hello {}", name)` com dois argumentos. Além disso, as macros são expandidas antes do compilador interpretar o significado do código, então uma macro pode, por exemplo, implementar um trait em um determinado tipo. Uma função não pode, porque é chamada em tempo de execução e um trait precisa ser implementado em tempo de compilação.
O `match` é uma expressão que permite combinar um valor com uma série de padrões e executar o código correspondente ao padrão correspondente. É semelhante a um switch em outras linguagens de programação. O `match` é frequentemente usado em Rust para lidar com enumerações, mas também pode ser usado com outros tipos de dados.
Enquanto a condição especificada for verdadeira, o bloco de código dentro do `while` será executado repetidamente. A condição é verificada antes de cada iteração do loop. Se a condição for falsa, o loop será interrompido e a execução continuará após o bloco `while`.
```rust
let mut i = 0;
while i <5{
println!("O valor de i é: {}", i);
i += 1;
}
```
Este exemplo imprimirá o valor de `i` cinco vezes, começando em 0 e incrementando em 1 a cada iteração, até que `i` seja igual a 5.
O `if let` é uma expressão condicional que permite verificar se um valor corresponde a um padrão específico e, em seguida, executar um bloco de código correspondente. É uma forma mais concisa de escrever um `match` que lida apenas com um caso.
A sintaxe básica é a seguinte:
```
if let PATTERN = EXPRESSION {
// code to execute if the pattern matches
}
```
Onde `PATTERN` é o padrão que estamos verificando e `EXPRESSION` é a expressão que estamos avaliando. Se `EXPRESSION` corresponder a `PATTERN`, o bloco de código dentro das chaves será executado. Caso contrário, o código será ignorado.
O `if let` é frequentemente usado em conjunto com a função `Option`, que representa um valor opcional que pode ser `Some(valor)` ou `None`. Podemos usar o `if let` para verificar se um valor `Option` é `Some` e, em seguida, desempacotá-lo para usar o valor subjacente. Por exemplo:
```
let my_number = Some(42);
if let Some(x) = my_number {
println!("The number is {}", x);
}
```
Neste exemplo, estamos verificando se `my_number` é `Some` e, em seguida, desempacotando o valor `42` e atribuindo-o a `x`. Se `my_number` fosse `None`, o bloco de código seria ignorado.
Um Arc pode usar Clone para criar mais referências sobre o objeto para passá-las para as threads. Quando a última referência apontando para um valor está fora do escopo, a variável é descartada.