Почему extended () ведет себя странно, когда дважды передает один и тот же список? - PullRequest
0 голосов
/ 04 апреля 2010

Меня очень смущает одна из тонкостей функции 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]

Это совершенно странно для меня. Я не могу понять использование этой функции, и кажется, что было бы действительно легко вызвать ее случайно, когда вы просто хотели вставить один список в другой и не понимали, что переменные ссылаются на один и тот же массив.

Документация гласит следующее:

Если они | Списки |: Добавить {expr2} к {expr1}.

Если задано {expr3}, вставьте элементы {expr2} перед элементом {expr3} в {expr1}.

Когда {expr3} равен нулю, вставьте перед первым элементом.

Если {expr3} равен len ({expr1}), тогда добавляется {expr2}.

Примеры:

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

Если {expr1} - это тот же список, что и {expr2}, то количество копируемых элементов равно исходной длине списка.

Например, когда {expr3} равен 1, вы получаете N новых копий первого элемента (где N - исходная длина списка).


Имеет ли это смысл, которого я не понимаю, или это просто эксцентричность?

1 Ответ

0 голосов
/ 04 апреля 2010

Я думаю, что я действительно понял это, когда писал, но, поскольку у меня был вопрос, который все отредактировал и все, я решил, что я мог бы также пройти через него.

extend () изменяет первый список на месте. Второй параметр доступен только для чтения. Таким образом, похоже, что он дублирует элементы второго списка по одному, вставляя их в первый. Когда оба эти списка одинаковы, это не очень хорошо работает. Но он не достаточно умен, чтобы справиться с этим крайним случаем, так что дела идут не так, как надо.

Я не нашел никаких документов, подтверждающих это, но гипотеза соответствует доказательствам. Я думаю, я мог бы прочитать исходный код для получения дополнительной информации.

Это все еще немного странно, так как я бы подумал, что, поскольку это " lists ", это будет работать немного по-другому, например, сначала дублируя весь список, а затем вставляя его в первый. просто обмениваясь указателями на голову / хвост. Это, вероятно, не будет быстрее, но это позаботится о крайнем случае. Может быть, это особенность, хотя. Я все еще открыт для предложений о причинах, по которым это может быть полезно.

В противном случае, я думаю, я отправлю сообщение об ошибке. Кто-нибудь знает, есть ли у vim публичный баг-трекер? Я чувствую странную запись на адрес электронной почты, не проверяя, является ли это известной проблемой в первую очередь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...