首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >F#匹配数组的开头

F#匹配数组的开头
EN

Stack Overflow用户
提问于 2014-11-17 13:43:18
回答 2查看 335关注 0票数 2

我有一个可能包含一个或多个数据帧的Byte[]缓冲区,我需要读取第一个字节才能知道实际帧的长度。

这是我想做的“不工作”的版本:

代码语言:javascript
运行
复制
let extractFrame (buffer:byte[]) =
  match buffer with 
    | [|head1;head2;head3;..|] when head2 < (byte)128 -> processDataFrame buffer head2
    | <...others....>
    | _ -> raise(new System.Exception())

基本上,我需要计算前三个字节,然后用缓冲区和帧的实际长度调用processDataFrame。根据标题,帧可以是数据、控件等.

这可以用任何类型的匹配(列表、序列、...etc.)来完成吗?或者我必须创建另一个只有标题长度的小数组?(我想避免这种情况)。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-11-17 13:58:02

如果要使用匹配,可以创建活动模式(http://msdn.microsoft.com/en-us/library/dd233248.aspx):

代码语言:javascript
运行
复制
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())
票数 3
EN

Stack Overflow用户

发布于 2014-11-17 14:01:25

我认为使用普通的if构造可能更容易做到这一点。

但是正如Petr所提到的,您可以使用活动模式并定义自己的模式,从数组中提取特定信息。为了建模您正在做的事情,我实际上使用了一个参数化的活动模式--您可以给出您需要的数组中的元素数,并且它会给出一个数组,例如,返回3个元素:

代码语言:javascript
运行
复制
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长度相匹配-编译器不能为您检查这一点。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26974042

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档