Trilhas
/
Rust
Rust
/
Programa
/
Funções
Fu

Funções em Rust

1 exercício

Sobre Funções

Funções são corpos de código que contêm uma ou mais instruções ou expressões. Uma função pode, opcionalmente, retornar um valor.

No estilo do Rust, nomes de funções usam snake case, e a definição de uma função é precedida pela palavra-chave fn. Por exemplo

fn do_nothing() {}

Os parênteses envolvem zero ou mais parâmetros, separados por vírgulas. Um parâmetro é uma ligação a um valor de um tipo específico que é passado para a função. Mesmo que não haja parâmetros, os parênteses continuam obrigatórios na definição da função. O valor de fato passado a um parâmetro é chamado de argumento.

A combinação de parâmetros e valor de retorno é conhecida como a assinatura da função. A assinatura de uma função exige que cada parâmetro tenha seu tipo anotado.

As chaves delimitam o corpo da função: suas instruções e expressões. Mesmo que a função não contenha instruções nem expressões, as chaves continuam obrigatórias na definição da função.

No exemplo a seguir, a função recebe um parâmetro do tipo i32, associa-o ao nome value e o imprime.

fn print_integer(value: i32) {
    println!("{value:?}");
}

Repare na definição do parâmetro. Cada parâmetro é definido no formato name: Type.

Uma função também pode retornar um valor. Por padrão, o resultado da última expressão é retornado. No exemplo a seguir, a função tem um parâmetro i32 e retorna o seu dobro.

fn double_integer(value: i32) -> i32 {
    value * 2
}

O -> i32 indica que a função retorna um i32. Ao contrário dos parâmetros, o valor retornado não tem nome.

É possível sair de uma função antes do fim com a palavra-chave return, assim:

fn long_function() -> i32 {
    let some_condition = false;
    // code snipped
    if (some_condition) {
        return 0;
    }
    // more code snipped
    42
}

const fn serve para definir uma função constante, que pode ser avaliada em tempo de compilação.

const fn compute_data_checksum() -> u128 {
  const DATA: &[u8] = include_bytes!("my_big_data_file");
  // checksum implementation is left as an exercise for the reader
}

/// This checksum is used to validate that the user has not tampered with proprietary configuration.
pub const DATA_CHECKSUM: u128 = compute_data_checksum();

Como funções constantes podem ser avaliadas em tempo de compilação, elas têm algumas restrições que funções normais não têm. Em especial, uma const fn só pode chamar outras funções também marcadas como const. Se essa restrição não for respeitada, o resultado é um erro de compilação.

const fn multiply_integer(value: i32) -> i32 {
    use std::time::SystemTime;
    if SystemTime::now().elapsed().unwrap().as_nanos() == 0 { // this line errors
        value * 2
    } else {
        value * 3
    }
}

Existem funções anônimas, que são abordadas no tópico closures.

Editar via GitHub O link abre em uma nova janela ou aba