F# 如何使用惯用F将数据数组转换为记录#

F# 如何使用惯用F将数据数组转换为记录#,f#,F#,我正在尝试创建一个与硬件交互的通信库。该协议由字节数组组成,其中包含一个头(源/目标地址、命令号、长度)和一个特定于命令的有效负载。我正在为每个命令创建记录类型,以使它们更加用户友好 有没有比将数组转换为记录更惯用的方法 let data = [0;1] type Rec = { A : int B : int } let convert d = { A = d.[0] B = d.[1] } 当记录大得多时,这会变得非常乏味。一些评论: 您的记录类型

我正在尝试创建一个与硬件交互的通信库。该协议由字节数组组成,其中包含一个头(源/目标地址、命令号、长度)和一个特定于命令的有效负载。我正在为每个命令创建记录类型,以使它们更加用户友好

有没有比将数组转换为记录更惯用的方法

let data = [0;1]
type Rec = {
    A : int
    B : int
}

let convert d =
  {
    A = d.[0]
    B = d.[1]
  }
当记录大得多时,这会变得非常乏味。

一些评论:

您的记录类型定义是假的-其中不应该有
=
。我想你想要

type Rec = {
    A : int
    B : int
}
您提到了字节数组,但您的
数据
值是一个列表。按索引访问列表项代价很高(O(n)),应该避免。如果要将其声明为数组,语法是
let data=[|0;1}]

但我想知道这里的唱片是否合适。如果您的目标是让一个函数接受一个字节数组并返回该数据的各种强类型解释,那么一个有区别的联合可能是最好的

也许是这样的:

// various possible command types
type Commands =
    | Command1 of byte * int    // maybe payload of Command1 is known to be an int
    | Command2 of byte * string // maybe payload of Command1 is known to be a string

// active pattern for initial data decomposition
let (|Command|) (bytes : byte[]) =
    (bytes.[0], bytes.[1], Array.skip 2 bytes)

let convert (bytes : byte[]) =
    match bytes with
    | Command(addr, 1uy, [| intData |]) ->
        Command1(addr, int intData)
    | Command(addr, 2uy, strData) ->
        Command2(addr, String(Text.Encoding.ASCII.GetChars(strData)))
    | _ ->
        failwith "unknown command type"

// returns Command1(0x10, 42)
convert [| 0x10uy; 0x01uy; 0x2Auy |]

// returns Command2(0x10, "foobar") 
convert [| 0x10uy; 0x02uy; 0x66uy; 0x6Fuy; 0x6Fuy; 0x62uy; 0x61uy; 0x72uy |]

正是我想要的。对不起,我在手机上打字,根本没有注意语法。