F# 4.6 預覽版正式公佈

1月24日,F# 4.6 預覽版正式公佈,與以往同樣,新版本的設計與開發過程是整個 F# 開源社區共同努力的結果,此次更新的具體討論內容能夠經過下面兩個連接來查看:git

此次更新的主要內容有:github

  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。code

模式匹配

因爲匿名記錄的特色,現階段還沒法對匿名記錄使用模式匹配解構,這是由於當咱們把匿名記錄中的某些字段在模式匹配中忽略掉的時候,可能會產生新的類型,如上面所說的,匿名記錄的類型標識是由其所有的字段決定的。對象

其餘的一些限制

  1. 沒法使用 CLIMutable 特性修飾,這也意味着匿名記錄是不可變的
  2. 匿名記錄沒法定義類成員(包括成員字段、屬性、方法等),這是由於記錄僅僅只是用來保存數據的,

ValueOption 模塊

FSharp.Core 4.6.0 中帶來了 ValueOption 模塊,爲 FSharp.Core 4.5.0 中引入的 ValueOption 類型帶來了大量的實用函數,詳情請見 RFC 說明頁面blog

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 生態。ci

以上就是 F# 4.6 的更新簡介,更加詳細的介紹能夠查看微軟博客的公告以及相關的 RFC 記錄。


同步發表於我的博客: F# 4.6 預覽版正式公佈

相關文章
相關標籤/搜索