Эта выборка от книжного Программирования на шоу Lua , как сделать надлежащую хвостовую рекурсию (в Lua, но должен относиться к Lisp также), и почему это лучше.
А последний вызов [хвостовая рекурсия] является своего рода goto, одетым как вызов. Последний вызов происходит, когда вызовы функции другой как его последнее действие, таким образом, он не имеет ничего иного, чтобы сделать. Например, в следующем коде, вызов к
g
является последним вызовом:function f (x) return g(x) end
После
f
вызовыg
, это не имеет ничего иного, чтобы сделать. В таких ситуациях программа не должна возвращаться к функции вызова, когда вызванная функция заканчивается. Поэтому после последнего вызова, программа не должна хранить информацию о функции вызова в стеке...., поскольку надлежащий последний вызов не использует стекового пространства, нет никакого предела на количество "вложенных" последних вызовов, которые может сделать программа. Например, мы можем вызвать следующую функцию с любым числом как аргумент; это никогда не будет переполнять стека:
function foo (n) if n > 0 then return foo(n - 1) end end
... Как я сказал ранее, последний вызов является своего рода goto. По сути, довольно полезное приложение надлежащих последних вызовов в Lua для программирования конечных автоматов. Такие приложения могут представить каждое состояние функцией; изменить состояние означает перейти в (или звонить) определенная функция. Как пример, давайте рассмотрим простую игру лабиринта. Лабиринт имеет несколько комнат, каждого максимум с четырьмя дверями: север, юг, восток и запад. На каждом шаге пользователь вводит направление перемещения. Если существует дверь в том направлении, пользователь переходит к соответствующей комнате; иначе программа печатает предупреждение. Цель состоит в том, чтобы пойти от начальной комнаты до заключительной комнаты.
Эта игра является типичным конечным автоматом, где текущая комната является состоянием. Мы можем реализовать такой лабиринт с одной функцией для каждой комнаты. Мы используем последние вызовы для перемещения от одной комнаты до другого. Маленький лабиринт с четырьмя комнатами мог быть похожим на это:
function room1 () local move = io.read() if move == "south" then return room3() elseif move == "east" then return room2() else print("invalid move") return room1() -- stay in the same room end end function room2 () local move = io.read() if move == "south" then return room4() elseif move == "west" then return room1() else print("invalid move") return room2() end end function room3 () local move = io.read() if move == "north" then return room1() elseif move == "east" then return room4() else print("invalid move") return room3() end end function room4 () print("congratulations!") end
, Таким образом, Вы видите при совершении рекурсивного вызова как:
function x(n)
if n==0 then return 0
n= n-2
return x(n) + 1
end
Это не хвост, рекурсивный, потому что у Вас все еще есть вещи сделать (добавьте 1) в той функции после того, как выполняется рекурсивный вызов. При вводе очень высокого количества, оно, вероятно, вызовет переполнение стека.
Раньше я не играл со встраиванием Google Maps (для подобных вещей я обычно сразу обращаюсь к API). Я попробовал несколько подходов:
Я подумал, что, возможно, синтаксис встраивания будет таким же, как у статических карт api. Поэтому я взял URL-адрес статических карт, скопировал из него параметры маркеров и попытался вставить его в URL-адрес iFrame. Это не сработало.
Я создал Google MyPlaces и настроил маркер , чтобы использовать тот, который вы указали. Это создало Тестовую карту с соответствующим значком маркера. Затем я взял код встраивания и вставил его на тестовую страницу и вуаля!