Как заставить lua работать последовательно

Я изучаю Lua через этот сайт. Я нахожусь в самом начале учебников и пробую эту программу (введите номер,x возвращает x!):

-- defines a factorial function
function fact (n)
  if n == 0 then
    return 1
  else
    return n * fact(n-1)
  end
end

print("enter a number:")
a = io.read("*number")  -- read a number
print(fact(a))

однако, когда я запускаю его,io.read кажется, перед приглашением. Я запускаю его в консоли Notepad++ следующим образом:

"C:Program FilesLua.1lua.exe" "PathTofactorial.lua"

вывод (по-видимому) пуст, но если я ввожу число, функция запускается.

5
enter a number:
120

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

1 ответов


происходит не то, что код выходит из строя, а то, что приглашение не отображается на терминал немедленно.

внутренне все, что вы выводите, хранится в буфере ввода-вывода операционной системой. Периодически буфер опустошается и его содержимое отображается на терминале (это вспыхнул). В большинстве систем терминал is линия буферизованный по умолчанию, что означает, что каждый раз, когда вы пишете конец строки характер-какой print() делает автоматически-он сбрасывается; в некоторых системах, однако, по умолчанию он полностью буферизованной, то есть он автоматически очищается только когда наполнится.

есть два способа решить эту проблему. Если вы хотите отключить или изменить буферизацию для все операции ввода-вывода в файле (и для этих целей терминал считается файлом), вы можете использовать file:setvbuf(); в частности, io.output():setvbuf("no") будет отключите буферизацию для стандартного вывода, то есть все, что вы пишете, будет отображаться немедленно. Вы также можете использовать io.output():setvbuf("line") включить буфферизацию, на системах, где это поддерживается, но не по умолчанию.

другой подход-вручную очистить буфер, что полезно, когда вы хотите, чтобы какой-то конкретный вывод отображался немедленно, но не хотите универсальное отключить буферизацию вывода. Вы можете сделать это с помощью file:flush(), которым сразу же смывает буфер, например:

-- no newline, so even on line-buffered systems this may not
-- display immediately
io.write("Enter a number: ")
-- so we force it to
io.flush()

отметим, что io.write() и io.flush() просто функции удобства для io.output():write() и io.output():flush(), т. е. они получают в текущий выходной файл, а затем вызвать :write() или :flush() на них.

(зачем вообще беспокоиться о буферизации? Потому что это быстрее - запись данных в терминал или файл стоит дорого, и писать одну большую вещь быстрее, чем писать много мелких вещей. В большинстве случаев, не имеет значения, если что-то не записывается в момент запуска кода, поэтому ОС сохраняет данные для записи в буфер, а затем делает одну большую запись, когда буфер заполняется.)