今天,我试着编写了一个elisp函数,除了函数返回时一直被抛出的错误外,所有的功能都很好。这是一个函数:(请原谅格式化,我还不知道如何缩进。)
(defun byte-is-readable (byte)
"Determine whether BYTE is readable or not.
Returns t or nil."
(if (and (<= byte 126) (>= byte 32)) t nil))
;; Read the 100 bytes of a file
;; If 10 in a row are not 'readable', it is safe to assume the file is a binary
(defun is-file-binary (file)
"Determine whether FILE is a binary file.
Returns t or nil."
(let* ((i 1)
(c 0)
(size (nth 7 (file-attributes file)))
(lim (if (< size 100) size 100)))
(while (< i lim)
(let ((char (with-temp-buffer
(insert-file-contents file)
(buffer-substring i (+ i 1)))))
(if (not (byte-is-readable (aref char 0)))
(setq c (+ c 1))
(setq c 0))
(if (= c 10) (return t)))
(setq i (+ i 1))))
nil)像这样调用它:(message "%s" (if (is-file-binary "/path/to/some/file") "true" "false")在返回true时工作文件,但在返回nil时抛出"if: No catch for tag:-catch nil-,t“。我猜这是因为没有得到正确的评估什么的。
我该怎么解决呢?
发布于 2013-11-08 16:11:04
错误来自于您在代码中使用了return。这是一个宏,它只在其他一些cl宏的上下文中进行有意义的扩展,例如loop。
我鼓励您使用loop而不是while,因为它允许隐藏一些乏味的实现细节,如计数器、throw - catch机制等。但是,如果您出于任何原因想要使用while,那么从while循环中分离出来的方法是使用:
(catch 'label (while <condition> ... (throw 'label <result>)))使用loop的代码版本。
(defun byte-readable-p (byte)
"Determine whether BYTE is readable or not.
Returns t or nil."
(cl-case byte
((?\n ?\r ?\t) t)
(otherwise (and (<= byte 126) (>= byte 32)))))
(defun file-binary-p (file)
"Determine whether FILE is a binary file.
Returns t or nil."
(with-temp-buffer
(insert-file-contents file)
(cl-loop for c across
(buffer-substring-no-properties
1 (min 100 (buffer-size)))
thereis (not (byte-readable-p c)))))
(file-binary-p (expand-file-name "~/.emacs"))
nil
(file-binary-p (expand-file-name "~/.emacs.d/elpa/w3m-20131021.2047/w3m.elc"))
t或者,更短的版本,使用高阶函数:
(defun file-binary-p (file)
"Determine whether FILE is a binary file.
Returns t or nil."
(with-temp-buffer
(insert-file-contents file)
(cl-find-if-not 'byte-readable-p
(buffer-substring-no-properties
1 (min 100 (buffer-size))))))注意,在传统的Lisp代码函数中,返回布尔值(通常称为“谓词”)是使用方案命名的:<word>p或<word>-<word>-p,而不是is-<word>。
https://stackoverflow.com/questions/19863249
复制相似问题