我有一个可能包含一个或多个数据帧的Byte[]缓冲区,我需要读取第一个字节才能知道实际帧的长度。
这是我想做的“不工作”的版本:
let extractFrame (buffer:byte[]) =
match buffer with
| [|head1;head2;head3;..|] when head2 < (byte)128 -> processDataFrame buffer head2
| <...others....>
| _ -> raise(new System.Exception())基本上,我需要计算前三个字节,然后用缓冲区和帧的实际长度调用processDataFrame。根据标题,帧可以是数据、控件等.
这可以用任何类型的匹配(列表、序列、...etc.)来完成吗?或者我必须创建另一个只有标题长度的小数组?(我想避免这种情况)。
发布于 2014-11-17 13:58:02
如果要使用匹配,可以创建活动模式(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())发布于 2014-11-17 14:01:25
我认为使用普通的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长度相匹配-编译器不能为您检查这一点。
https://stackoverflow.com/questions/26974042
复制相似问题