博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
F#新Bug,小心! module 里的泛型变量。
阅读量:4647 次
发布时间:2019-06-09

本文共 1167 字,大约阅读时间需要 3 分钟。

        原则上,.Net不支持静态泛型变量,但是 F# 的语法支持,如:

        module Mithra =

                let Empty<'T> = Seq.empty <'T>

       但是,这只是个语法糖而已。把这 F# 代码块编译成一个库,在C#里调用,即可看到,没有 Empty 变量,只有 Empty 函数。也就是说,这个“
Empty
”在 F# 里面,只是看起来像变量,实际上是在执行一个函数。
       这有什么关系呢?答:有关系。 
 
       参照老赵的《》,如果有泛型变量的话。F# 下,实现逆泛型是轻而易举的事。

    // 声明泛型函数变量

      let _getBytes<'T>  = ref Unchecked.defaultof< 'T->byte[] >

      // 泛型变量具现化,赋值

 

      _getBytes<int16> := BitConverter.GetBytes

      _getBytes<int32> := BitConverter.GetBytes

      _getBytes<int64> := BitConverter.GetBytes

      _getBytes<String> := Encoding.UTF8.GetBytes

      // 取出函数

 

      let GetBytes<'T> = !_getBytes<'T>  

        上面的代码,理论上已经实现了逆泛型,但是当调用 GetBytes 的时候,却发现 GetBytes 还是 null 值!原因何在?
        就是因为 _getBytes 不是变量,而是个函数。每次调用_getBytes,都会重新计算,返回一个 null 的引用值。因此上 F#中 module 里允许泛型变量,这不仅仅是个语法糖,还是个有毒的语法糖。使用的时候,必须先理解其实现实质,不然就会蹦出错误。
 
      下面,给出使用泛型类替代泛型变量后,正确的代码:

        module Mithra =

        type Cache<'T> () =

            static memberval GetBytes: 'T -> byte[] = Unchecked.defaultof< 'T ->byte[] > with get, set 

        Cache<int16>.GetBytes <- BitConverter.GetBytes

        Cache<int32>.GetBytes <- BitConverter.GetBytes

        Cache<int64>.GetBytes <- BitConverter.GetBytes

        Cache<String>.GetBytes <- Encoding.UTF8.GetBytes 

        let GetBytes<'T> = Cache<'T>.GetBytes

 

 

 

转载于:https://www.cnblogs.com/greatim/p/3943358.html

你可能感兴趣的文章
⑥python模块初识、pyc和PyCodeObject
查看>>
object-c中管理文件和目录:NSFileManager使用方法
查看>>
Kibana:分析及可视化日志文件
查看>>
nodejs pm2使用
查看>>
cocos2d-x 3.10 PageView BUG
查看>>
装饰器的基本使用:用户登录
查看>>
CSS选择器总结
查看>>
mysql中sql语句
查看>>
head/tail实现
查看>>
sql语句的各种模糊查询语句
查看>>
vlc 学习网
查看>>
Python20-Day05
查看>>
Real World Haskell 第七章 I/O
查看>>
C#操作OFFICE一(EXCEL)
查看>>
【js操作url参数】获取指定url参数值、取指定url参数并转为json对象
查看>>
移动端单屏解决方案
查看>>
web渗透测试基本步骤
查看>>
使用Struts2标签遍历集合
查看>>
angular.isUndefined()
查看>>
第一次软件工程作业(改进版)
查看>>