为什么这些记录类型冲突?

时间:2009-05-07 11:25:23

标签: f# record

考虑以下记录类型:

type drCode1Body = {DrCode : byte ; Name : string ; Timestamp : DateTime ; Size : uint32 ; Options : byte}
type drCode2Body = {DrCode : byte ; LastBlock : byte ; BlockNumber : uint16 ; BlockSize : uint16 ; BlockData : array<byte>}
type drCode4Body = {DrCode : byte ; Name : string ; Timestamp : DateTime ; Options : byte ; Size : uint16 ; Data : array<byte>}

如果我尝试创建这样的实例(代码片段,而不是完整代码):

{DrCode = 1uy ; Name = name ; Timestamp = timestamp ; Size = size ; Options = options}        

{DrCode = 2uy ; LastBlock = lastBlock ; BlockNumber = blockNumber ; BlockSize = blockSize ; BlockData = blockData}

{DrCode = 4uy ; Name = name ; Timestamp = timestamp ; Options = options ; Size = size ; Data = data }

它不接受第一行有效。 即使第一行中的大小是uint32值。 它只是说“没有为字段'数据'赋予任务。”

更改参数名称也无济于事, 我也尝试过这个:

 {new drCode1Body with DrCode = 1uy and Name = name and Timestamp = timestamp and Size = size and Options = options} 

然后我得到以下异常:

此表达式的类型为drCode1Body,但此处与drCode4Body类型一起使用

虽然我清楚地指出了我想要的记录类型。

发生了什么事?

1 个答案:

答案 0 :(得分:3)

你可以写一个例如。

{drCode1Body.DrCode = 1uy ; Name = name ; ...

消除记录字段标签重叠的歧义。

(实际上,当F#开始阅读标签时,它会向后搜索带有这些标签的第一个记录类型......一旦看到DrCode和Name,它就会认为'你肯定是指drCode4Body!'...提供第一个字段标记上的分配,您可以在正确的方向上引导类型推断。)

以下代码编译在F#1.9.6.2:

#light
open System
type drCode1Body = 
  {DrCode : byte; Name : string; Timestamp : DateTime; Size : uint32; Options : byte}
type drCode2Body = 
  {DrCode : byte; LastBlock : byte; BlockNumber : uint16; BlockSize : uint16; BlockData : array<byte>}
type drCode4Body = 
  {DrCode : byte; Name : string; Timestamp : DateTime; Options : byte; Size : uint16; Data : array<byte>}
let name = ""
let timestamp = DateTime.Now 
let size = 0u
let size2 = 0us
let options = 0uy
let lastBlock = 0uy
let blockNumber = 0us
let blockSize = 0us
let blockData = [|0uy|]
let data = [|0uy|]
let r1 = {drCode1Body.DrCode = 1uy; Name = name; Timestamp = timestamp; Size = size; Options = options}        
let r2 = {DrCode = 2uy; LastBlock = lastBlock; BlockNumber = blockNumber; BlockSize = blockSize; BlockData = blockData}
let r3 = {DrCode = 4uy; Name = name; Timestamp = timestamp; Options = options; Size = size2; Data = data }