Erlang队列行为不一致

队列的内部表示有所不同,具体取决于:

  • 它是使用queue:from_list()函数创建的
  • 或者使用queue:new()函数并使用它们填充元素。
  • 简单代码:

    L = [1,2,3], 
    Q = queue:from_list(L),  % convert it to Queue.
    L2 = queue:to_list(Q),   % convert back to list.
    QL2 = queue:from_list(L2), % And create queue representation
    true =  Q =:= QL2. 
    

    到目前为止,一切都很好,

  • Q看起来像: {[3],[1,2]}
  • QL2看起来像{[3],[1,2]}
  • 现在通过元素创建队列:

    Q0 = queue:new(),
    Q1 = queue:in(1,Q0),
    Q2 = queue:in(2,Q1),
    Q3 = queue:in(3,Q2),
    Q =:= Q3.
    

  • 问: {[3],[1,2]}
  • Q3: {[3,2],[1]}
  • Q和Q3的内部表示不同。

    如果我们做这样的事情:

    Q3x = queue:from_list(queue:to_list(Q3))
    

    我们得到相同的表示: {[3],[1,2]}

    现在:

    Q =:= Q3x.
    

    如预期那样真实

    这意味着我们无法比较两个队列的平等,只需使用如下代码:

    Q == Q3. 
    

    它是一个错误还是一个功能?


    问题是:如果你排队或out_r队列中的元素,他们是否给出相同的结果? 答案是肯定的,没有不一致的行为。

    内部表示是一个“不透明”的元组,其内容取决于队列的历史记录,它是如何填充结束清空的。 这种结构用于优化队列中的操作,并且基于实际表示编写代码是不可靠的,因为可能(即使不太可能)这种表示更改。 其中一个后果是,哟无法将队列与模式匹配或==进行比较,并且没有接口来执行此操作,我猜这是因为此用例很少。 如果你真的需要它,我想更有效的解决方案是比较队列的结果:to_list / 1: queue:to_list(Q) == queue:to_list(Q3).


    根据称为“摊销分析”的算法复杂性估计技术,一些操作可能为其他操作“付费”。 在具有队列的这种特殊情况下,有两个列表表示队列:前列表(用于恒定加入时间)和后列表(用于恒定访问时间)。 前端列表中的元素有时可能会迁移到后端列表中,并在实施时发生。

    我发现一篇论文“Rebecca Fiebrink普林斯顿大学的摊销分析解释”,对这个主题非常有帮助。 其中一个例子就是你的问题。

    链接地址: http://www.djcxy.com/p/66293.html

    上一篇: Erlang queue inconsistent behaviour

    下一篇: Ambiguous assignment in erlang using date & time