/ / F # Casting Operators - conversão de elenco, f #, conversão de tipo

Operadores de Fundição F # - fundição, f #, conversão de tipo

Qual é a diferença entre os seguintes operadores de fundição F #? Não consigo entender por que e como eles são diferentes.

(type) X
X :> type
X :?> type

Respostas:

20 para resposta № 1

O primeiro não é um elenco em F #, embora se você estiver acostumado com C # pode parecer que funciona como um. Mas isso na verdade está invocando uma conversão de tipo função (gostar int), e os parênteses não são realmente necessários (e só podem tornar tudo mais confuso).

(int) "4" // the number 4 - this is a conversion, not a cast
int "4"   // same thing, but idiomatic
int "NaN" // compiles but throws an exception at runtime
(int) (box 4) // doesn"t compile because int doesn"t do downcasts, just known conversions

Observe que isso funciona para tipos primitivos, porque existem funções de conversão predefinidas, mas não funcionará para tipos arbitrários:

(bigint) 1 // no such conversion function, so this is a compile-time error

A diferença entre os outros dois é que :> realiza upcasts (de um tipo para um supertipo, que é sempre seguro) e :?> executa downcasts (de um tipo para um subtipo, que pode falhar, portanto, o "?" No meio).

Também são nomeados upcast e downcast operadores que podem ser usados ​​de maneira semelhante:

5 :> obj                 // upcast int to obj
(upcast 5 : obj)         // same
(box 5) :?> int          // downcast an obj to int (successfully)
(downcast (box 5) : int) // same
(box "5") :?> int        // downcast an obj to int (unsuccessfully)

Em alguns contextos, o tipo de destino do upcast ou downcast pode ser inferido com sucesso, caso em que você não precisa das anotações de tipo ao usar o upcast ou downcast operadores, embora você sempre precise fornecer um argumento de tipo para o :> ou :?> operadores (embora você possa fornecer _ se você espera que seja inferido):

List.map (fun x -> x + 1) (downcast (box [1]))
List.map (fun x -> x + 1) (box [1] :?> _)