gpt4 book ai didi

generics - F# 中算术转换为泛型类型

转载 作者:行者123 更新时间:2023-12-02 21:32:46 25 4
gpt4 key购买 nike

我尝试编写一个对算术类型进行泛型转换的函数,例如接收 uint64 类型参数的函数,然后转换为与类型参数相同的类型。我的想法是:

let convert<'T> (x:uint64) = 'T x

但是这段代码无法编译,在尝试了几种方法后我卡在这里:

let convert<'T> (x:uint64) = 
match Unchecked.defaultof<'T> with
| :? uint32 -> uint32 x
....

那么我怎样才能在 F# 中编写这样的通用算术转换呢? (我刚刚开始学习,所以我的问题可能很愚蠢,请放轻松)。

最佳答案

:?类型检查仅允许(至少这是我的理解)测试您匹配的表达式类型的子类型。如'T可以是任何类型,编译器无法判断 uint32是其子类型,因此不可能进行类型测试。

要检查匹配表达式中的“任意”类型,您需要 box首先将值转换为 obj 。由于所有其他类型都是 obj 的子类型(Object 在 C# 和整个 CLR 中),然后您可以测试您想要的任何类型。

正如您所注意到的,仅此还不够,因为匹配表达式的所有分支都需要返回相同的类型。因为(据我所知)所有数字类型的唯一公共(public)父类(super class)型又是 obj ,需要再次对每个转换进行装箱,然后将匹配的结果向下转换为 'T 。理论上,这不是 100% 类型安全,但在这种情况下,您知道转换将保持不变。

let convert<'T> (x:uint64) = 
match box Unchecked.defaultof<'T> with
| :? uint32 -> uint32 x |> box
| :? int -> int x |> box
:?> 'T

哦,在性能关键的现实世界代码(紧密循环等,大量调用)中使用这样的东西可能不是一个好主意,因为数字类型是在堆栈上分配的值类型,而每个数字装箱都会在堆上分配一个必须进行垃圾收集的对象(iirc,装箱 4 字节整数会创建一个 16 字节对象,因此差异相当大)。

关于generics - F# 中算术转换为泛型类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36782413/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com