openlang

Почему значения меняются при рекурсивных вызовах?

Как такое возможно? Что мне стоит проверить?

Рекурсивная функция visit(board) получает структуру, которая внутри функции называется incoming.

В nextBoard есть два среза, left и right. Каждый срез содержит небольшие структуры cell с компонентами label1, label2 и bool.

Внутри visit(incoming) у меня написано:

nextBoard := advance(incoming)

savedInput := incoming

visit(nextBoard)

Других вызовов visit внутри этой функции нет.

Это предыстория, а вот сама проблема: допустим, visit вызывается на глубине рекурсии 27 и спускается ещё на 12 уровней. Затем возвращается к глубине 27. Теперь incoming отличается от содержимого до вызова. Странно, что savedInput тоже изменился, причём ровно так же, как incoming. nextBoard по-прежнему содержит то же, что и перед вызовом.

Я хочу понять, как это получается? Все эти 3 переменные имеют область видимости функции, а НЕ пакета.

Ещё немного об изменениях incoming: у срезов left и right len равен 7. Срез right возвращается с изменённым 7-м элементом по сравнению с исходным?

Я знаю, что где-то между глубинами 27 и 39 седьмой элемент right заменяется седьмым элементом left с перевёрнутым булевым значением, а left теряет свой 7-й элемент. Это изменение выполняет функция advance(incoming).

Точнее, когда incoming возвращается на глубину 27, left остаётся исходным, а right изменён описанным выше образом, то есть right[6]=left[6] с перевёрнутым булевым значением.

Я подозреваю, что срезы внутри срезов всё ещё указывают на общую с оригиналом память. Это кажется единственным объяснением одинаковых изменений incoming и savedInput. Но почему incoming вообще должен отличаться после этого вызова?

Спасибо, что уделили время и прочитали всё это.

Есть ли что-то конкретное, что нужно проверить? Может, я неверно понимаю эффект записи savedInput:=incoming ? Я пробовал и :=, и = с заранее объявленным savedInput.

Переведено с английскогоПоказать оригинал

Разговор продолжается 2

Следуя доводам

Другие стороны того же вопроса

  1. Один и тот же вызов с sink, сначала копия, потом перенос

    Nim 2 решает, копировать или переносить, в каждой точке вызова. Не на уровне proc. Тот же аргумент, та же proc. Первый вызов…

    Ответы 2Последняя активность nim
  2. Отложить изменяемое заимствование блока очистки до его исполнения

    Как написать в Rust устойчивую к панике конструкцию, похожую на Java try { ... } finally { ... }, чтобы блоки try и finally м…

    Ответы 2Последняя активность rust
  3. Ввод массивов символов через указатели

    Когда пытаюсь вводить с клавиатуры данные в массивы char, программа каждый раз падает. Как можно удобно считывать с клавиатур…

    Ответы 2Последняя активность c