Clojure中的块注释

129

如何在Clojure中注释多行代码?

10个回答

159

事实上,有一种方法!


(comment

(defn hey [] ("嗨!你好!"))

看看我吧! )

只需用 (comment ..) 把你的注释包装起来即可 :)

玩得开心!


4
我原以为我会错过#||#,但现在情况比想象中好多了。 - unj2
4
希望你在使用Clojure时玩得开心。 :) - Rayne
15
注意:似乎(comment ...)中的内容需要是正确的形式;例如,(comment hello :world)是可以的,但是(comment hello: world)会产生异常。【编辑:】看起来我在发布这条评论之前应该先阅读Greg Hewgill的答案...噢好吧,无论如何我还是保留它,以防有人做了和我一样的事情。 - paul
21
警告:(comment) 宏会扩展成 nil。使用 #_ 来注释单个表达式,或者使用 #_(comment ...) 来注释多个表达式而不插入 nil。 - treat your mods well
1
它让我想起了这个宏:https://dev59.com/j1DTa4cB1Zd3GeqPJ4iJ - Felipe
对我没用 - 因为我想要注释的代码块在if语句内部,仍然被视为参数。下面的#_方法更好。 - Robert3452

109

Clojure 支持 #_ 读取宏,该宏可完全跳过下一表达式。此功能在有关 Clojure Reader 的页面中提到。还有 comment 宏 具有类似的效果,但实现方式不同。

以上两者都要求您要注释掉的东西是一个语法上正确的 S-表达式。

一些 Lisp 方言具有可以包含任意文本的多行注释,但我没有看到 Clojure 中有这样的注释。


22
Clojure 没有多行任意文本注释形式。我提交了一个补丁,添加了 #|......|# 注释,但被拒绝了,因为这不是期望的功能。因此,它不太可能很快被添加进来。 - amalloy
7
@amalloy: 这样做的原因是什么?只是没必要吗,还是有反对意见? - Ted
2
我经常模仿文学编程风格写长注释。我只使用emacs重新排列多行注释(在*scratch*缓冲区中,在多行的; ;;或者;;;后面输入一些无关紧要的内容,将光标放在分号后的第一个单词上,然后按下Meta-Q键)。 - Reb.Cabin
你可以使用 #_" 来打开一个多行自由格式的文本注释,并用 " 关闭它。唯一需要注意的是,你需要在其中转义双引号。 - Rachel K. Westmacott
注意:您也可以堆叠 #_。因此,#_#_#_ 可以注释掉接下来的三个表单。 - Rachel K. Westmacott

29

双引号(字符串字面量)允许添加任意文本(不仅仅是适当的S形式):

(comment "

public class HelloWorld {
    public static void main(String[] args) {
        System.out.print("Hello, World");
        System.out.println();
    }
}

")

4
好的,我会尽力进行翻译。“nice trick that worked for me!”的意思是“好的技巧,对我有用!”。“Hello World”中的引号为什么不需要转义是怎么可能的呢? - marathon
9
这只是运气而已。Ivan的例子分为4个形式:第一种形式是一个字符串,第二种形式是符号“Hello”,第三种形式是符号“World”,第四种形式是另一个字符串。“comment”会忽略所有形式。因此,在这个例子中,我们很幸运,“Hello, World”被解析为合法的Clojure代码。但这并不适用于任意文本。例如,“(comment"print("/foo")")”将会抛出错误,“Invalid token: /foo”。 - John Wiseman

18

其他例子非常好,我只想再添加一个技巧:

有时你想注释掉一些代码行,但是仍然希望编译器编译它并报告任何错误(例如,在顶级命名空间中执行的一组命令,稍后在REPL中执行)。

在这种情况下,我喜欢用(fn[].....)包装代码,这意味着它仍然会被编译,只是不会被调用。


15

9
在使用emacs和cider时,经常使用命令M-x comment-region

3
我知道的方法有多种:
第一种是使用comment宏:它仅仅是不评估注释体内的所有代码(但它仍然检查平衡的括号/方括号)。如果您熟悉paredit,那么如果您想要注释一些sexp调用,它不会花费太多时间。
(comment 
 (println 1))

然而,它仍会检查括号匹配。因此,如果您有不平衡的括号,您的代码将无法编译(导致java.lang.RuntimeException:EOF while reading)。

另一种方法是使用#_(即放弃宏):它将丢弃下一个Sexp,这是我个人偏爱的方式(键入更快,通常在调试Sexp时我都会这样做):

#_(println 1)

它还会检查未匹配的分隔符:因此,如果您有不平衡的括号,它也无法编译。
最后,有一个“;”字符,它将注释该行(类似于其他语言的注释功能),并且编译器将完全忽略它。如果要注释多行,则需要在所有行前加上;,这通常很麻烦,但通常文本编辑器会在选择多行后使用命令为您完成。
;  (println 1)
;  (println 1 also won't break

2
在Emacs中,您可以使用命令M-;(即M-x comment-dwim的快捷方式)来注释或取消注释任何标记的文本/代码区域,因此只要整个函数或一组功能包含在该区域中,您就可以相当容易地注释或取消注释该区域。有关函数M-;的Emacs参考手册可以在这里找到。

0
Clojure 还支持一个双井号 #_ #_ 读取宏,该宏会完全跳过下两个表单。这对于在映射中注释掉键和多行值非常有用。
示例
{
:db-connector "jdbc"
#_ #_ :auto-offset-reset    {:dev     "earliest"
                             :default "latest"}
}

0

对于一个较长的注释块,宏 #_ 或 (comment ...) 并不像专有软件那样有效,所以我使用 VSCODE(OS X) 来进行注释块。

  1. 高亮所需注释的内容
  2. 在 vscode 中按下 command+shift+p
  3. 找到 "Add Line Comment"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接