Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Function Emacs Lisp:“您必须遵守《全国人大常委会关于维护互联网安全的决定》及中华人民共和国其他有关法律法规。”;如果:标签--cl block nil--,t";当返回零时_Function_Emacs_Elisp - Fatal编程技术网

Function Emacs Lisp:“您必须遵守《全国人大常委会关于维护互联网安全的决定》及中华人民共和国其他有关法律法规。”;如果:标签--cl block nil--,t";当返回零时

Function Emacs Lisp:“您必须遵守《全国人大常委会关于维护互联网安全的决定》及中华人民共和国其他有关法律法规。”;如果:标签--cl block nil--,t";当返回零时,function,emacs,elisp,Function,Emacs,Elisp,今天我试着编写一个elisp函数,除了函数返回nil时不断抛出的一个错误外,其他都很好。函数如下:(请原谅格式化,我还不确定如何缩进。) (defun字节是可读的(字节) “确定字节是否可读。 返回t或nil。“ (如果(和(=字节32))t nil) ;; 读取文件的100字节 ;; 如果一行中有10个文件不“可读”,则可以安全地假定该文件是二进制文件 (defun是文件二进制(file) “确定文件是否为二进制文件。 返回t或nil。“ (让*((i)1) (c 0) (大小(第n个7(文件

今天我试着编写一个elisp函数,除了函数返回nil时不断抛出的一个错误外,其他都很好。函数如下:(请原谅格式化,我还不确定如何缩进。)

(defun字节是可读的(字节)
“确定字节是否可读。
返回t或nil。“
(如果(和(=字节32))t nil)
;; 读取文件的100字节
;; 如果一行中有10个文件不“可读”,则可以安全地假定该文件是二进制文件
(defun是文件二进制(file)
“确定文件是否为二进制文件。
返回t或nil。“
(让*((i)1)
(c 0)
(大小(第n个7(文件属性文件)))
(lim(如果(<尺寸100)尺寸100)))
(while(
像这样调用它:
(消息“%s”(if(is file binary)/path/to/some/file)“true”或“false”)
在返回true时对file起作用,但在返回nil时抛出“if:No catch for tag:--cl block nil--,t”。我猜这是因为nil的计算不正确或其他原因


如何修复它?

错误源于您在代码中使用了
return
。这是一个宏,仅在其他一些
cl
宏(例如
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
我鼓励您使用
循环
而不是
while
,因为它允许隐藏无趣的实现细节,例如计数器、
抛出
-
捕获
机制等。但是,如果出于任何原因,您想使用
while
循环,则打破
while
循环的方法是:

(catch 'label (while <condition> ... (throw 'label <result>)))

或者,更简短的版本,使用高阶函数:

(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代码中,函数返回布尔值(通常称为“谓词”)使用以下方案命名:
p
--p
而不是
is-

在每次通过WHILE循环时,您似乎都在创建一个新的临时缓冲区,并将文件内容加载到其中。这似乎效率不高。为什么不在WHILE周围使用-temp-buffer?
(使用临时缓冲区(插入文件内容文件)(虽然(
通过这种方式,您只需加载文件内容一次,而不是最多加载100次——对于小文件,这不会有什么区别,但是,由于您将整个文件加载到缓冲区中,对于大文件,这很有可能。(额外积分:只加载所需的字节。)此外,您根本不需要中断WHILE循环;您可以简单地让它自己耗尽,然后在C中计算“可读”字节数。然后,用
)替换let表单末尾的空零,如果少于10,函数将返回t“可读”字节,如果有10个或更多字节,则为零。您也可以取消LIM绑定,因为您只在一个位置使用它;只需从LET绑定表单中删除该绑定,然后使用
(if(表单为“在您的测试中调用”的第二个参数。“ArnnMulle:考虑将您的注释作为回答。例如,它们提供了与WVXVW的答案一样多的答案。您不需要所有这些:<代码>(如果(和(=字节32))nIL))
,除非你真的关心
t
作为非
nil
值。这就足够了:
(和(=字节32))
。工作起来很有魅力,谢谢。我对函数的功能有点困惑。它们是否检查所有100个字节都是“可读的”?因为如果文件中有“可读”字符,那么这将失败(elf文件以字母elf开头,ZIP以PK开头),但它没有。@ronmrdechai函数搜索文件开头100个或更少字节内的第一个字节(实际上是字符),该字节超出了
byte-readable-p
设置的范围。
(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))))))