我有一个Byte[]
缓冲区,可能包含一个或多个数据帧,我需要读取第一个字节以了解实际帧的长度。
这是一个非工作的"我想做的版本:
let extractFrame (buffer:byte[]) =
match buffer with
| [|head1;head2;head3;..|] when head2 < (byte)128 -> processDataFrame buffer head2
| <...others....>
| _ -> raise(new System.Exception())
基本上,我需要评估前三个字节,然后使用缓冲区和帧的实际长度调用processDataFrame
。根据标题,框架可以是数据,控制等......
这可以通过任何匹配(列表,序列等等)来完成吗?或者我是否必须创建另一个只有标题长度的小数组?(我想避免这种情况)。
答案 0 :(得分:3)
如果您想使用匹配,可以创建活动模式(http://msdn.microsoft.com/en-us/library/dd233248.aspx):
let (|Head1|_|) (buffer:byte[]) =
if(buffer.[0] (* add condition here *)) then Some buffer.[0]
else None
let (|Head2|_|) (buffer:byte[]) =
if(buffer.[1] < (byte)128) then Some buffer.[1]
else None
let extractFrame (buffer:byte[]) =
match buffer with
| Head1 h1 -> processDataFrame buffer h1
| Head2 h2 -> processDataFrame buffer h2
........
| _ -> raise(new System.Exception())
答案 1 :(得分:3)
我认为使用普通if
构造实际上这可能更容易。
但正如Petr提到的,您可以使用活动模式并定义自己的模式,从阵列中提取特定信息。为了模拟你正在做的事情,我实际上会使用一个参数化的活动模式 - 你可以从你需要的数组中给它一些元素的数量,它会给你一个数组,例如: 3个元素:
let (|TakeSlice|_|) count (array:_[]) =
if array.Length < count then None
else Some(array.[0 .. count-1])
let extractFrame (buffer:byte[]) =
match buffer with
| TakeSlice 3 [|head1;head2;head3|] when head2 < (byte)128 ->
processDataFrame buffer head2
| <...others....>
| _ -> raise(new System.Exception())
此方法的一个缺点是您的模式[|h1; h2; h3|]
必须与您指定的长度匹配3
- 编译器无法为您检查此内容。