Я хочу получить эффект статической переменной, используя defun
внутри let
с лексической привязкой для создания замыкания. Однако при байтовой компиляции файла я получаю предупреждение. Я делаю что-то не так, или если нет, есть ли способ подавить это предупреждение?
Я создал MCVE:
;; -*- lexical-binding: t -*-
(let ((count 0))
(defun increase-count ()
(interactive)
(setq count (1+ count))
(message "Count is: %d" count))
;; The warning happens here.
(increase-count))
Код работает должным образом: функция increase-count
выводит «Count is: n», где n увеличивается при каждом вызове. Однако при байтовой компиляции этого файла я получаю следующее предупреждение:
In end of data:
mcve.el:11:1:Warning: the function ‘increase-count’ is not known to be
defined.
Мне кажется, что increase-count
всегда следует определять перед вызовом в конце блока let. Разве это не так?
byte-compilation
lexical-scoping
defun
lexical-binding
Уилл Кункель
источник
источник
defun
не делает то, что, как вы думаете, он делает, он всегда создает определение верхнего уровня. Элисп, в конце концов, не Схема ...Ответы:
Способ байтового компилятора решить, будет ли определена функция или нет, очень «наивен» и обманывается даже в вашем «очевидном» случае. Но вы можете написать это так, чтобы компилятор понимал, что происходит:
Конечно, еще лучше было бы улучшить логику байтового компилятора: патчи приветствуются для этого.
источник
Чтобы подавить предупреждение байт-компилятора, попробуйте добавить это перед вашим кодом, начиная со столбца 0 (крайний левый):
C-h f declare-function
говорит тебе:источник
FILEONLY
аргумент для рассматриваемого случая? Кстати, я бы дал тот же ответ ;-).FILEONLY
мне здесь не нужно. Что, казалось бы, указывает на то, чтоcheck-declare
распознаетf
иg
определяет.f
иg
имеет смысл только в контексте emacs.stackexchange.com/q/39439 ?FILEONLY
мне здесь это не нужно. Что, казалось бы, указывает на то, чтоcheck-declare
признаетincrease-count
defun. ;-)Я считаю , размещая определение в вопросе внутри
eval-and-compile
также поверхностно достичь того же результата , как и в Стефана правильный ответ :Я, однако, едва знаком с тонкостями использования
eval-and-compile
и, кроме того, не ожидаю, что этот подход каким-либо образом превосходит.источник