【问题标题】:Why does Symfony provide an OrderedHashMap为什么 Symfony 提供 OrderedHashMap
【发布时间】:2018-09-01 21:30:37
【问题描述】:

Symfony 提供了一个OrderedHashMap。它的documentation states

与关联数组不同,映射会跟踪添加和删除键的顺序。此顺序会在迭代过程中反映出来。

我对这种说法感到困惑,因为我认为 PHP 关联数组实际上已经是有序映射。我在 SO 上发现了这个问题,这证实了我之前的假设:Are PHP Associative Arrays ordered?

我想知道,如果 Symfony 开发人员不知道 PHP 数组已经是有序映射,或者我不了解 Symfony 的 OrderedHashMap 的角色

【问题讨论】:

    标签: php symfony associative-array symfony3.x ordered-map


    【解决方案1】:

    当然,PHP 的数组是有序映射。

    但是 Symfony 的 OrderedHashMap 与 PHP 的数组有一些不同的行为(例如,功能)。

    OrderedHashMap 支持迭代期间的并发修改。这意味着您可以在 foreach 循环中插入和删除元素,并且迭代器将相应地反映这些更改。但是迭代中的array是复制的(Copy-On-Write),任何修改都不会反映在循环中。

    $map = new OrderedHashMap();
    $map[1] = 1;
    $map[2] = 2;
    $map[3] = 3;
    
    foreach ($map as $index => $value) {
        echo "$index: $value\n"
        if (1 === $index) {
            $map[1] = 4;
            $map[] = 5;
        }
    }
    

    如果您使用array,您将获得不同的输出。在 array 的迭代中,循环不会看到数字 5

    关于“为什么?”:在Symfony's codebase 中搜索。只有一个地方可以使用OrderedHashMap,它用于存储表单的子项。 new InheritDataAwareIterator($this->children) 使用它来迭代。所以我认为答案是帮助处理表单的孩子。

    感谢@fishbone:

    所以好处不是排序,而是循环修改它的能力。

    【讨论】:

    • 这并不能解释为什么他们说关联数组不跟踪顺序。所以好处不是排序,而是循环修改它的能力
    【解决方案2】:

    一般来说,不仅在 Symfony 的上下文中,除了附加实现的特性外,面向对象的结构比 intstringarray 等原始类型更受欢迎,因为它们可以注入到类中进行单元测试。

    面向对象的结构也可以强制执行不变量,而原始类型只能保存没有任何行为的数据。

    【讨论】:

    • 不正确,因为php的数组是通过Copy-On-Write实现的。传递数组就像传递对象一样轻松。
    • 所以尝试从 10 个不同的地方修改并返回该数组。
    • 请看我对肖恩回答的评论
    • 在Symfony的代码库中OrderedHashMap的用法只有少数:github.com/symfony/form/…children已经是private,没有机会通过不同的地方触发COW。
    • 传递参数但不做任何事情的实际用法是什么?
    猜你喜欢
    • 1970-01-01
    • 2016-04-24
    • 1970-01-01
    • 2017-08-15
    • 1970-01-01
    • 1970-01-01
    • 2018-09-13
    • 2017-09-19
    • 1970-01-01
    相关资源
    最近更新 更多