casting - F# 类型转换运算符

标签 casting f# type-conversion

以下 F# 转换运算符有何区别?我似乎无法理解它们为什么以及如何不同。

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

最佳答案

第一个不是 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

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

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

其他两者之间的区别在于 :> 执行向上转换(从类型到父类(super class)型,这始终是安全的),而 :> 执行向下转换(从类型到父类(super class)型)类型到子类型,这可能会失败,因此 '?' 位于中间)。

还有名为 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)

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

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

关于casting - F# 类型转换运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31616761/

相关文章:

swift - 从类型创建数组类型

c++ - 从 int 转换为 struct 时出现问题

c - ASCII 到十进制值

c# - 从函数中提取函数名

asp.net - 操作数数据类型 varchar 对于求和运算符无效 - 过程错误更正

Python:Pandas - 对象到数据框中的字符串类型转换

generics - 带有数组的 Swift countElements()

python - 如何在 Pandas 中实现 dtype 转换器功能?

f# - 为什么即使使用连续传递风格,遍历大型二叉树也会导致堆栈溢出?

f# - 从接口(interface)设计具有隐藏底层实现的 F# 类型