Partilhar via


Elenco e conversões (F#)

Este tópico descreve o suporte para conversões de tipo em F#.

Tipos de aritméticos

F# fornece os operadores de conversão para conversões aritméticas entre vários tipos primitivos, como entre inteiro e tipos de ponto flutuante. Os operadores de conversão integral e char verificou e formulários desmarcados; Operadores de ponto do flutuante e o enum o operador de conversão do não. Os formulários não verificados são definidos em Microsoft.FSharp.Core.Operators e os formulários selecionados são definidos em Microsoft.FSharp.Core.Operators.Checked. Os formulários selecionados de excedentes e geram uma exceção de tempo de execução se o valor resultante exceder os limites do tipo de destino.

Cada um desses operadores tem o mesmo nome que o nome do tipo de destino. Por exemplo, no código a seguir, na qual os tipos explicitamente são anotados, byte aparece com dois significados diferentes. A primeira ocorrência é o tipo e o segundo é o operador de conversão.

let x : int = 5

let b : byte = byte x

A tabela a seguir mostra os operadores de conversão definidos em F#.

Operador

Descrição

byte

Converta em bytes, um tipo não assinado de 8 bits.

sbyte

Converta em byte assinado.

int16

Converta um inteiro assinado de 16 bits.

uint16

Converta um inteiro não assinado de 16 bits.

int32, int

Converta um inteiro assinado de 32 bits.

uint32

Converta um inteiro não assinado de 32 bits.

int64

Converta um inteiro assinado de 64 bits.

uint64

Converta um inteiro não assinado de 64 bits.

nativeint

Converta um inteiro nativo.

unativeint

Converta para um inteiro não assinado de nativo.

float, double

Converta um IEEE de precisão dupla de 64 bits número de ponto flutuante.

float32, single

Converta um IEEE de precisão simples de 32 bits que número de ponto flutuante.

decimal

Converter em System.Decimal.

char

Converter em System.Char, um caractere Unicode.

enum

Converta um tipo enumerado.

Além de para tipos primitivos internos, você pode usar esses operadores com tipos que implementam op_Explicit ou op_Implicit métodos com assinaturas apropriado. Por exemplo, o int o operador de conversão funciona com qualquer tipo que fornece um método estático op_Explicit que leva o tipo como um parâmetro e retorna int. Como uma exceção especial para a regra geral que os métodos não podem ser sobrecarregados pelo tipo de retorno, você pode fazer isso para op_Explicit e op_Implicit.

Tipos enumerados

O enum operador é um operador genérico que leva um parâmetro de tipo que representa o tipo da enum para converter para. Quando o converte para um tipo enumerado, digite inferência tenta determinar o tipo da enum que você deseja converter. No exemplo a seguir, a variável col1 não for anotado explicitamente, mas seu tipo é inferido do Test de igualdade posterior. Portanto, o compilador pode deduzir que você estiver convertendo para uma Color enumeração. Como alternativa, você pode fornecer uma anotação de tipo, como com col2 o exemplo a seguir.

type Color =
    | Red = 1
    | Green = 2
    | Blue = 3

// The target type of the conversion is determined by type inference.
let col1 = enum 1
// The target type is supplied by a type annotation.
let col2 : Color = enum 2 
do
    if (col1 = Color.Red) then
       printfn "Red"

A projeção de tipos de objeto

A conversão entre tipos em uma hierarquia de objetos é fundamental para programação orientada a objeto. Há dois tipos básicos de conversões: a projeção (upcasting) e a projeção para baixo (Baixar). Conversão de uma hierarquia significa a projeção de uma referência de objeto derivado a uma referência de objeto base. Uma conversão é garantida para funcionar como a classe base é na hierarquia de herança da classe derivada. Projetando uma hierarquia de uma referência de objeto de base para uma referência de objeto derivado terá êxito somente se o objeto, na verdade, é uma instância do tipo correto de destino (derivado) ou um tipo derivado do tipo de destino.

F# fornece a operadores para esses tipos de conversões. O :> operador projeta na hierarquia e o :?> operador projeta para baixo da hierarquia.

Upcasting

Em muitas linguagens orientadas a objeto, o upcasting é implícito; no F#, as regras são ligeiramente diferentes. Upcasting é aplicado automaticamente quando você passar argumentos para métodos em um tipo de objeto. No entanto, para funções de let vinculados em um módulo, upcasting não é automática, a menos que o tipo de parâmetro é declarado como um tipo flexível. Para obter mais informações, consulte Tipos flexíveis (F#).

O :> operador executa uma conversão estática, que significa que o sucesso do tom é determinado em tempo de compilação. Se uma conversão que usa :> compilado com êxito, ele é uma conversão válida e não possui nenhuma chance de falhas em tempo de execução.

Você também pode usar o upcast o operador para executar tal uma conversão. A expressão a seguir especifica uma conversão da hierarquia.

upcast expression

Quando você usa o operador elevado, o compilador tenta inferir o tipo que você está convertendo a partir do contexto. Se o compilador não pode determinar o tipo de destino, o compilador reporta um erro.

Baixar

O :?> operador executa uma conversão dinâmica, que significa que o sucesso do tom é determinado em tempo de execução. Uma conversão que usa o :?> operador não estiver marcada em tempo de compilação; mas, em tempo de execução é feita uma tentativa para converter para o tipo especificado. Se o objeto for compatível com o tipo de destino, a projeção é bem-sucedida. Se o objeto não é compatível com o tipo de destino, o tempo de execução gera um InvalidCastException.

Você também pode usar o downcast operador para executar uma conversão de tipo dinâmico. A expressão a seguir especifica uma conversão para baixo na hierarquia para um tipo que é inferido a partir do contexto do programa.

downcast expression

Para o operador elevado, se o compilador não é possível inferir um tipo de destino específico do contexto, ele reporta um erro.

O código a seguir ilustra o uso de :> e :?> operadores. O código ilustra que o :?> é melhor usado quando você conhece a conversão seja bem-sucedida, pois ele lança InvalidCastException se a falha de conversão. Se você não souber que uma conversão seja bem-sucedida, um teste de tipo que usa um match a expressão é melhor porque evita a sobrecarga de gerar uma exceção.

type Base1() =
    abstract member F : unit -> unit
    default u.F() =
     printfn "F Base1"

type Derived1() =
    inherit Base1()
    override u.F() =
      printfn "F Derived1"


let d1 : Derived1 = Derived1()

// Upcast to Base1.
let base1 = d1 :> Base1

// This might throw an exception, unless
// you are sure that base1 is really a Derived1 object, as
// is the case here.
let derived1 = base1 :?> Derived1

// If you cannot be sure that b1 is a Derived1 object,
// use a type test, as follows:
let downcastBase1 (b1 : Base1) =
   match b1 with
   | :? Derived1 as derived1 -> derived1.F()
   | _ -> ()

downcastBase1 base1

Porque os operadores genéricos downcast e upcast dependem de inferência de tipo para determinar o tipo de argumento e o retorno no código acima, você pode substituir

let base1 = d1 :> Base1

com

base1 = upcast d1

No código anterior, o tipo de argumento e os tipos de retorno são Derived1 e Base1, respectivamente.

Para obter mais informações sobre testes de tipo, consulte Corresponder expressões (F#).

Consulte também

Outros recursos

Referência de linguagem do F#

Histórico de alterações

Date

History

Motivo

Setembro de 2010

Adicionadas informações sobre a sobrecarga op_Explicit e op_Implicit retornar tipo.

Aprimoramento de informações.