When to use “if” and “when” in Clojure?
什么时候比另一个更好?
一个比另一个快吗?还是唯一的区别是返回false或nil?
当您只有一个真实情况和一个虚假情况并且不需要隐式的do块时,请使用if。相反,当您只需要处理真实情况和隐式do时,应使用when。速度没有区别,这是使用最惯用的风格的问题。
1 2 3 4 5 6 7
| (if (my-predicate? my-data)
(do-something my-data)
(do-something-else my-data))
(when (my-predicate? my-data)
(do-something my-data)
(do-something-additionally my-data)) |
在if情况下,如果my-predicate?返回真实结果,则仅运行do-something,而在when情况下,同时执行do-something和do-something-additionally。
-
如果我只需要处理真实的情况,而不需要隐式的do(在这种情况下使用更常规的方法)怎么办?
-
使用when。 do部分是优先选择when而不是if的另一个充分理由,而不是必要的先决条件。
当您有两个不同的表达式时,请使用if:用于true子句和用于false子句。
when和when-not在两种情况下很有用:
-
当您要有条件地执行一个或多个(隐式do帮助)有条件的纯操作时;
-
当您要评估某些谓词为true(或false(对于when-not的情况))并在相反情况下返回nil的情况。
only difference is the return of false or nil
false和nil之间没有主要区别,因为两者在逻辑上下文中均求值为false。
-
Ive注意到Clojure和Common Lisp中when的使用在风格上有所不同。在CL中,如果您担心测试失败时的返回值,则有些人认为使用when是不好的。在这种情况下,您应该在if的最后一个子句中显式返回nil。有道理,在相同情况下在Clojure中使用when是很常见的,因为大多数代码在Clojure中纯粹是起作用的:很少忽略返回值。如果Clojure程序员遵循CL约定,则when很少用于纯功能代码中。 (有时nil与false很重要。)
-
@Mars很有趣,在Clojure中false和nil共存是真的吗?我无法想到false不能完成nil无法做到的事情。
-
我认为总体思路是:nil表示"序列中没有剩余的内容",而false只是表示错误。 nil也表示false的事实允许简单地测试序列的结尾。另外,您可以执行(get {:a 1 :b nil} :c false)之类的操作。在这里,这里,这里和这里有更多讨论。
-
另外:因为nil的含义类似于"空序列"以及false,所以next和rest在应用于nil时具有含义,但是在应用于false时会引发异常。 nil的其他有趣用途包括some,它可以像谓词一样工作,因为它在失败时返回nil,但实际上不是谓词(因此名称中没有"?")和keep(请参阅doc页)。但是,我不完全理解为什么Clojure应该同时具有nil和false。
-
@Mars在CL中,建议与Clojure的建议基本相同,请参见。 google-styleguide.googlecode.com/svn/trunk/和cs.cmu.edu/Groups/AI/html/faqs/lang/lisp/part1/fa??q-doc-4.htm。从后者开始:除非要强调返回值,否则切勿将2参数IF或3参数if与第二个参数nil一起使用。使用when和UNLESS代替。当IF子句嵌入在SETQ(例如(SETQ X (IF (EQ Y Z) 2 NIL)))中时,您将需要强调返回值。