Compartilhar via


Inferência de tipos

Este tópico descreve como o compilador F# infere os tipos de valores, variáveis, parâmetros e valores retornados.

Inferência de tipo em geral

A ideia de inferência de tipo é que você não precisa especificar os tipos de constructos F#, exceto quando o compilador não pode deduzir conclusivamente o tipo. Omitir informações explícitas de tipo não significa que F# é uma linguagem tipada dinamicamente ou que os valores em F# são digitado fracamente. F# é uma linguagem tipada estaticamente, o que significa que o compilador deduz um tipo exato para cada construção durante a compilação. Se não houver informações suficientes para o compilador deduzir os tipos de cada construção, você deverá fornecer informações de tipo adicionais, normalmente adicionando anotações de tipo explícitas em algum lugar no código.

Inferência de tipos de parâmetro e retorno

Em uma lista de parâmetros, você não precisa especificar o tipo de cada parâmetro. No entanto, F# é uma linguagem tipada estaticamente e, portanto, cada valor e expressão tem um tipo definido em tempo de compilação. Para esses tipos que você não especifica explicitamente, o compilador infere o tipo com base no contexto. Se o tipo não for especificado de outra forma, ele será inferido para ser genérico. Se o código usar um valor inconsistentemente, de modo que não haja um único tipo inferido que atenda a todos os usos de um valor, o compilador relatará um erro.

O tipo de retorno de uma função é determinado pelo tipo da última expressão na função.

Por exemplo, no código a seguir, os tipos a de parâmetro e b o tipo de retorno são inferidos int porque o literal 100 é do tipo int.

let f a b = a + b + 100

Você pode influenciar a inferência de tipo alterando os literais. Se você fizer o 100 a uint32 acrescentando o sufixo u, os tipos de a, be o valor retornado for inferido como uint32.

Você também pode influenciar a inferência de tipo usando outros constructos que implicam restrições ao tipo, como funções e métodos que funcionam apenas com um tipo específico.

Além disso, você pode aplicar anotações de tipo explícitas a parâmetros de função ou método ou a variáveis em expressões, conforme mostrado nos exemplos a seguir. Os erros resultarão se ocorrerem conflitos entre restrições diferentes.

// Type annotations on a parameter.
let addu1 (x : uint32) y =
    x + y

// Type annotations on an expression.
let addu2 x y =
    (x : uint32) + y

Você também pode especificar explicitamente o valor retornado de uma função fornecendo uma anotação de tipo após todos os parâmetros.

let addu1 x y : uint32 =
   x + y

Um caso comum em que uma anotação de tipo é útil em um parâmetro é quando o parâmetro é um tipo de objeto e você deseja usar um membro.

let replace(str: string) =
    str.Replace("A", "a")

Generalização Automática

Se o código de função não depender do tipo de um parâmetro, o compilador considerará o parâmetro genérico. Isso é chamado de generalização automática e pode ser um poderoso auxílio para escrever código genérico sem aumentar a complexidade.

Por exemplo, a função a seguir combina dois parâmetros de qualquer tipo em uma tupla.

let makeTuple a b = (a, b)

O tipo é inferido para ser

'a -> 'b -> 'a * 'b

Informações adicionais

A inferência de tipo é descrita com mais detalhes na Especificação da Linguagem F#.

Consulte também