Conversões cast 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 os tipos de inteiro e o ponto flutuante . Os operadores de conversão de integral e char verificou e formulários não verificados; os operadores de ponto flutuante e o enum não operador de conversã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 umaexceção de tempo de execuçãose 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 operadorde conversão.
let x : int = 5
let b : byte = byte x
A tabela a seguir mostra os operadores de conversão definidos em F#.
Operator |
Descrição |
---|---|
byte |
Converta em byte, um tipo de 8 bits sem sinal. |
sbyte |
Converta em assinado byte. |
int16 |
Converta para um inteirode assinado de 16 bits. |
uint16 |
Converta em um de 16 bits sem sinal inteiro. |
int32, int |
Converta para um inteirode assinado de 32 bits. |
uint32 |
Converta em um de 32 bits sem sinal inteiro. |
int64 |
Converta para um inteirode assinado de 64 bits. |
uint64 |
Converta em um de 64 bits sem sinal inteiro. |
nativeint |
Converta uminteirode nativo. |
unativeint |
Converta um unsigned nativo inteiro. |
float, double |
Converta um número de ponto flutuante do IEEE 64-bit precisão dupla. |
float32, single |
Converta em um número de ponto flutuante de 32 bits de precisão simples IEEE. |
decimal |
Converter em System.Decimal. |
char |
Converter em System.Char, um caractere Unicode . |
enum |
Converta um tipo enumerado. |
Além tipos primitivos internos, você pode usar esses operadores com tipos que implementam op_Explicit ou op_Implicit métodos com assinaturas apropriadas. Por exemplo, o int de conversão operador funciona com qualquer tipo que oferece ummétodo de estáticoop_Explicit que usa o tipo como um parâmetro e retorna int. Como especial exceção à 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 aceita um parâmetro que representa o tipo de digitar a enum para converter para. Quando o converte para um tipo enumerado, digite as tentativas de inferência para 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 da de igualdade posterior teste. Portanto, o compilador pode deduzir o que você estiver convertendo para uma Color enumeração. Como alternativa, você pode fornecer um tipo de anotação, como ocorre com col2 no 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"
Você também pode especificar o tipo deenumeração de destinoexplicitamente como um tipo parâmetro, como no código a seguir:
let col3 = enum<Color> 3
Observe que a enumeração projeta trabalho somente se o tipo subjacente da enumeração é compatível com o tipo que está sendo convertido. No código a seguir, a conversão falhar a compilar devido à incompatibilidade entre de int32 e uint32.
// Error: types are incompatible
let col4 : Color = enum 2u
Para mais informações, consulte Enumerações (F#).
A projeção de tipos de objeto
Conversão entre tipos em uma hierarquia de objeto , é fundamental para o objeto-oriented programming. Existem 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 de derivada para uma referência de objeto de base. Uma conversão é garantida para funcionar, desde que a classe base está na hierarquia de herança da classederivada. A projeção para baixo de uma hierarquia, a partir de uma referência de objeto de base para uma referência de objeto de derivado terá êxito somente se o objeto é realmente uma instância do tipo de destino correto (derivado) ou um tipo derivado do tipo de destino.
F# fornece a operadores para esses tipos de conversões. O :> operador projeta superiores da hierarquia e o :?> operador projeta para baixo na hierarquia.
Upcasting
Em muitos objeto-idiomas, o upcasting está implícito; no F#, as regras são ligeiramente diferentes. Upcasting é aplicado automaticamente quando você passa argumentos para métodos em um tipo de objeto . No entanto, para let - funçõeslimite em um módulo, upcasting não é automática, a menos que o tipo de parâmetro é declarado como um tipo flexível. Para mais informações, consulte Tipos flexíveis (F#).
O :> operador executa uma estático converter, o que significa que o sucesso do tom é determinado em tempo de compilar . Se uma conversão que usa :> compilado com êxito, ele é uma conversão válido e possui sem chance de falha em tempo de execução.
Você também pode usar o upcastde operador para realizar tal conversão. A expressão a seguir especifica uma conversão na hierarquia.
upcast expression
Quando você usa o operadorde 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 um dinâmico converter, o que significa que o sucesso do tom é determinado em tempo de execução. A projeção de que usa a :?> operador não estiver marcada em tempo de compilar ; 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 downcastde 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 docontextodo programa.
downcast expression
Como para o operadorde elevado, se o compilador não é possível inferir um tipo específico de destino do contexto, ele reporta um erro.
O código a seguir ilustra o uso da :> e :?> operadores. O código ilustra que a :?> operador InvalidCastException se a conversão falhar. Se você não souber que uma conversão seja bem-sucedida, um tipo teste que usa um match 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 Expressões match (F#).