F#Casting Operators

use*_*285 13 f# casting type-conversion

以下F#强制运算符之间有什么区别?我似乎无法理解为什么以及它们如何不同.

(type) X
X :> type
X :?> type
Run Code Online (Sandbox Code Playgroud)

kvb*_*kvb 22

第一个不是F#中的强制转换,但如果你已经习惯了C#,它可能看起来像是一个.但这实际上是在调用类型转换函数(如int),并且实际上并不需要括号(并且可能会使一切变得更加混乱).

(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
Run Code Online (Sandbox Code Playgroud)

请注意,这适用于基本类型,因为有预定义的转换函数,但它不适用于任意类型:

(bigint) 1 // no such conversion function, so this is a compile-time error
Run Code Online (Sandbox Code Playgroud)

另外两个之间的区别在于:>执行向上转换(从类型到超类型,这总是安全的)并:?>执行向下转换(从类型到子类型,可能会失败,因此'?'在中间).

还有一些名称upcastdowncast运算符可以以类似的方式使用:

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)
Run Code Online (Sandbox Code Playgroud)

在某些情况下,可以成功推断出向上或向下转换的目标类型,在这种情况下,在使用upcastdowncast运算符时不需要类型注释,而您总是需要为:>:?>运算符提供类型参数(尽管您可以供应,_如果你期望它被推断):

List.map (fun x -> x + 1) (downcast (box [1]))
List.map (fun x -> x + 1) (box [1] :?> _)
Run Code Online (Sandbox Code Playgroud)