1月24日,F# 4.6 预览版正式公布,与以往一样,新版本的设计与开发过程是整个 F# 开源社区共同努力的结果,这次更新的具体讨论内容可以通过下面两个链接来查看:

这次更新的主要内容有:

  1. 匿名记录类型(Anonymous Records)
  2. ValueOption 模块
  3. ListArraySeq 新增的 tryExactlyOne

匿名记录类型(Anonymous Records)

快速上手

F# 新增了匿名记录类型,举个例子:

// {| ... |} 用来声明一个匿名的记录
let data = {| X = 1; Y = "abc" |}
// val data : {| X : int; Y : string |} let result = data.X + data.Y.Length // 匿名记录同样可以使用 with 关键字复制并更新
let newData = {| data with Z = data.X + 5 |} // 匿名记录还可以作为函数的参数使用
let someFunc (d: {| X : int; Y: string |}) =
printfn "X: %d; Y: %s" d.X d.Y

为什么我们需要这个新特性

  1. F# 中声明一个记录类型真的很繁琐,尤其是我们只需要一次性的引用一个记录类型的时候
  2. C# 3.0 引入的匿名对象在 F# 中找不到对应的概念,这在把 C# 代码转换为 F# 代码的时候带来很大的痛苦
  3. C# 7.0 为元组类型添加了命名字段,而当前的 F# 会忽略掉这部分的信息

匿名记录的类型

为了保证程序集中拥有相同结构的匿名记录类型的一致性,编译器会使用 SHA1 算法根据匿名记录的字段名列表(排序后)为匿名记录生成唯一的类型标识。

  • {| X : int |}{| Y : int |} 会被生成为两个不同的类型
  • {| X : int; Y : int |} 与 {| Y : int; X : int |} 是同一个类型
  • 匿名记录可以使用 struct 关键字修饰,这样生成出来的就是结构体类型的记录了

与 Record 的不同

拷贝更新

匿名记录的拷贝更新功能非常的灵活,这是因为匿名记录的拷贝更新并不要求原始类型与结果类型一致,所以下面的代码都是成立的:


type RefRecord = { X : int; }
let refRecord = { X = 1 } // 结果类型不必与原始类型相同
let dataA = {| refRecord with Y = "string" |} // 结果为 {| X = 1; Y = "string" |}
let dataB = {| dataA with Y = 23333 |} // 结果为 {| X = 1; Y = 23333 |} // 甚至还可以从引用类型中拷贝数据到结构体中,反过来也是可以的
let dataC = struct {| dataB with Z = true |} // 结果为 {| X = 1; Y = 23333; Z = true |}

不过在现阶段,我们还是无法通过拷贝更新的方法用匿名记录来创建 Record。

模式匹配

由于匿名记录的特点,现阶段还无法对匿名记录使用模式匹配解构,这是因为当我们把匿名记录中的某些字段在模式匹配中忽略掉的时候,可能会产生新的类型,如上面所说的,匿名记录的类型标识是由其全部的字段决定的。

其他的一些限制

  1. 无法使用 CLIMutable 特性修饰,这也意味着匿名记录是不可变的
  2. 匿名记录无法定义类成员(包括成员字段、属性、方法等),这是因为记录仅仅只是用来保存数据的,

ValueOption 模块

FSharp.Core 4.6.0 中带来了 ValueOption 模块,为 FSharp.Core 4.5.0 中引入的 ValueOption 类型带来了大量的实用函数,详情请见 RFC 说明页面

ListArraySeq 新增的 tryExactlyOne

这个函数类似于 LINQ 中的 SingleOrDefault(),不过它并不会抛出异常,而是以一个温和的 Option 类型作为返回值:

List.tryExactlyOne []
// None
List.tryExactlyOne [1]
// Some 1
List.tryExactlyOne [1; 2]
// None Array.tryExactlyOne null
// ArgumentNullException
Array.tryExactlyOne [||]
// None
Array.tryExactlyOne [|1|]
// Some 1
Array.tryExactlyOne [|1; 2|]
// None Seq.tryExactlyOne null
// ArgumentNullException
Seq.tryExactlyOne (Seq.ofList [])
// None
Seq.tryExactlyOne (Seq.ofList [1])
// Some 1
Seq.tryExactlyOne (Seq.ofList [1; 2])
// None

最后

尽管 F# 4.6 只是一个小小的功能特性更新,但是匿名记录出现给 F# 开发带来了新的活力,除了能够减少代码量之外,匿名记录也让 F# 开发者能够更加轻松的使用以 C# 为主导的 .NET 生态。

以上就是 F# 4.6 的更新简介,更加详细的介绍可以查看微软博客的公告以及相关的 RFC 记录。


同步发表于个人博客: F# 4.6 预览版正式公布

F# 4.6 预览版正式公布的更多相关文章

  1. .NET 7 预览版2 的亮点之 NativeAOT 正式合并入 .NET 主线

    .NET 中备受追捧和期待已久的功能NativeAOT终于出现在本周的.NET 7 预览版2中,该项目的工作仍在继续,该版本将 NativeAOT 从实验性的 dotnet/runtimelab re ...

  2. 终于等到你!微软正式上线 Windows Terminal 预览版

    前一段时间,一直在知乎.技术社区收到技术小伙伴们的终极拷问:微软Build 大会上提到的**6月中旬**要上Windows store 的 Windows Terminal 到底啥时候可以用到呀? 有 ...

  3. 微软发布了ASP.NET WebHooks预览版

    微软 近期发布了ASP.NET WebHooks的预览版 ,这是一个可用于创建及使用Webhook功能的库.WebHooks支持MVC 5及WebApi 2. Webhook是一种通过HTTP实现用户 ...

  4. win10最新预览版9926使用评估

    1月21日微软发布会,终于在周一发布了新的预览版本Build 9926,这个并不是客户预览版,仍然是开发者预览版,如图: 如果要查看自己的windows 10是那个版本,打开运行窗口,输入如下命令: ...

  5. Swift 3.0首个开发者预览版将在5月12日释出

    Swift团队在博客中宣布Swift 3.0语言首个开发者预览版将于5月12日释出,正式版将在4-6周之后推出.开发者预览阶段并无确定的更新周期和计划,不过Swift团队称努力将其控 制在4-6周内. ...

  6. Windows 10简体中文最新预览版Build 9926

    Windows 10 消费者预览版全新特性: • 全新的开始菜单Win 10的开始菜单产生了较大改变,磁贴界面在原有磁贴概念的基础上进行了大幅度的调整,新的磁贴界面开始支持纵向滚动,并可以利用开始按钮 ...

  7. 传Windows 9预览版今秋发布

    据ZDNet长期关注微软动态的资深人士玛丽•乔•弗利(Mary Jo Foley)称,Windows 9预览版将会在9月或者10月推出.按照这一进度,代号为“Threshold’”的Windows 9 ...

  8. Azure SQL 数据库最新版本现已提供预览版

     Tiffany Wissner  数据平台营销高级总监 我们之前在11月宣布将提供新的预览版,在该预览版中我们引入了接近完整的 SQL Server 引擎兼容性和更为高级的性能,这些都代表了下一代的 ...

  9. VS2015预览版中的C#6.0 新功能(三)

    VS2015预览版中的C#6.0 新功能(一) VS2015预览版中的C#6.0 新功能(二) Using static 使用using StaticClass,你可以访问StaticClass类里的 ...

随机推荐

  1. python基础知识笔记-集合

    集合使用花括号将元素之间用逗号隔开即可.集合的输出里不会出现相同的元素.集合中有并集.交集.差集等,以下为一些简单的表达: def main(): list1=[1,1,2,2,3,3] print( ...

  2. sqoop2的相关配置,启动,停止命令(转)

    原博客地址:http://blog.csdn.net/u012772782/article/details/52949181 sqoop2配置: 一.添加sqoop2到系统环境变量中: export ...

  3. MongoDB 聚合函数

    概念 聚合函数是对一组值执行计算并返回单一的值 主要的聚合函数 count distinct Group MapReduce 1.count db.users.count() db.users.cou ...

  4. Linux软件安装——软件包分类、RPM包管理

    1.软件包分类: (1)源码包: 优点:开源,即用户可以看到源代码,用户可以修改源代码:可以自由选择所需的功能:软件是编译安装,效率更高. 缺点:需要手动安装,安装慢. (2)二进制包(RPM包.系统 ...

  5. 【数论】[素数筛,phi]P3601签到题

    题目描述 给出l,r,要求求出\(\sum_{i = l}^r (i - phi[i]) mod 666623333\) \(1\leq l\leq r\leq 10^{12}\),\(r - l \ ...

  6. STL中find和sort的用法总结

    STL算法 STL 提供能在各种容器中通用的算法(大约有70种),如插入.删除.查找.排序等. 许多算法操作的是容器上的一个区间(也可以是整个容器),因此需要两个参数,一个是区间起点元素的迭代器,另一 ...

  7. Linux中的文件

    一般情况下,每个存储设备或存储设备的分区(存储设备是硬盘.软盘.U盘 ..)被格式化为文件系统后,都会有两部份,一部份是iNode,另一部份是Block.Block是用来存储数据用的,而iNode就是 ...

  8. nginx rewrite实战实例

    本部分内容为nginx生产环境中使用的场景示例. 域名跳转(域名重定向) 示例1(不带条件的): server{ listen ; server_name www.aminglinux.com; re ...

  9. attempt to call method 'getDataString' (a nil value)

    错误: LUA ERROR: [: attempt to call method 'getDataString' (a nil value) 在合并cocos和quick的时候,在EventCusto ...

  10. 干货收藏 | Java 程序员必备的一些流程图

    阅读本文大概需要 6 分钟. 转载自:https://juejin.im/post/5d214639e51d4550bf1ae8df 1.Spring 的生命周期 Spring 作为当前 Java 最 ...