为什么extend()在两次传递相同列表时会引发奇怪的行为?

时间:2010-04-03 23:10:50

标签: vim

我对vimscript extend()函数的一个细微之处感到困惑。

如果你使用它来扩展一个包含另一个列表的列表,那么它几乎可以满足你的期望,即将第二个列表插入到第三个参数给出的索引的第一个列表中:

      let list1 = [1,2,3,4,5,6] | echo extend(list1,[1,2,3,4,5,6],5)
      " [1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 6, 6]

但是如果你给它两次相同的列表就会开始绊倒一些。

      let list1 = [1,2,3,4,5,6] | echo extend(list1,list1,0)
      " [1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6]
      let list1 = [1,2,3,4,5,6] | echo extend(list1,list1,1)
      " [1, 1, 1, 1, 1, 1, 1, 2, 3, 4, 5, 6]
      let list1 = [1,2,3,4,5,6] | echo extend(list1,list1,2)
      " [1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 5, 6]
      let list1 = [1,2,3,4,5,6] | echo extend(list1,list1,3)
      " [1, 2, 3, 1, 2, 3, 1, 2, 3, 4, 5, 6]
      let list1 = [1,2,3,4,5,6] | echo extend(list1,list1,4)
      " [1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 5, 6]
      let list1 = [1,2,3,4,5,6] | echo extend(list1,list1,5)
      " [1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 6]
      let list1 = [1,2,3,4,5,6] | echo extend(list1,list1,6)
      " [1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6]

更令人困惑的是,当使用两个不同的变量引用列表时,此行为适用:

      let list1 = [1,2,3,4,5,6] | let list2 = list1 | echo extend(list1,list2,4)
      " [1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 5, 6]

这对我来说完全是奇怪的。我无法理解这个功能的用途,当你只想将一个列表插入另一个列表并且没有意识到变量引用相同的数组时,似乎很容易调用它。 / p>

文档说明以下内容:

  

如果是| Lists |:将{expr2}附加到{expr1}。

     

如果给出{expr3},请在{expr1}中的{expr3}项之前插入{expr2}项。

     

当{expr3}在第一项之前插入为零时。

     

当{expr3}等于len({expr1})时,会附加{expr2}。

     

示例:

        :echo sort(extend(mylist, [7, 5]))
        :call extend(mylist, [2, 3], 1)
  

当{expr1}与{expr2}相同时,则复制的项目数等于List的原始长度。

     

例如,当{expr3}为1时,您将获得第一个项目的N个新副本(其中N是列表的原始长度)。


这是否以某种我没有得到的方式有意义,还是只是一种怪癖?

1 个答案:

答案 0 :(得分:0)

我想我实际上是在发帖时弄清楚了这一点,但由于我的问题都经过编辑,所以我想我也可以继续使用它。

extend()修改第一个列表。第二个参数是只读的。所以看起来它正在做的是将第二个列表中的元素一个接一个地复制到第一个列表中。当两者都是相同的列表时,这不能很好地工作。但是处理这种边缘情况并不够聪明,所以事情就好了。

我没有找到任何文件来支持这一点,但该假设与证据相符。我想我可以去阅读源代码了解更多信息。

这仍然有点奇怪,因为我会认为,因为这些是“列表”它会有点不同,例如首先复制整个列表然后将其下载到第一个列表中通过交换头/尾的指针。这可能不会更快,但它会处理边缘情况。也许这是一个功能。我仍然愿意接受这可能有用的原因的建议。

否则我想我会提交错误报告。有人知道vim是否有某个公共bug跟踪器吗?我觉得写电子邮件地址很奇怪,而没有先查看它是否是一个已知问题。