【问题标题】:When to use let vs. if-let in Clojure在 Clojure 中何时使用 let 与 if-let
【发布时间】:2010-01-06 00:55:39
【问题描述】:

什么时候使用if-let 而不是let 会使代码看起来更好,它对性能有什么影响吗?

【问题讨论】:

    标签: clojure


    【解决方案1】:

    我想当您想在代码的“then”部分引用if 条件的值时,应该使用if-let

    即而不是

    (let [result :foo]
      (if result
        (do-something-with result)
        (do-something-else)))
    

    你写:

    (if-let [result :foo]
      (do-something-with result)
      (do-something-else))
    

    这更简洁一些,并且可以节省您进一步缩进的级别。就效率而言,您可以看到宏扩展不会增加太多开销:

    (clojure.core/let [temp__4804__auto__ :foo]
      (if temp__4804__auto__
        (clojure.core/let [result temp__4804__auto__]
          (do-something-with result))
        (do-something-else)))
    

    这也说明不能在代码的“else”部分引用绑定。

    【讨论】:

    • 另外,if-let 的绑定向量中不能有超过 2 种形式。例如:(if-let [a 20 b nil] (println a)) - 不起作用!
    • @SusheelJavadi 你可以创建自己的 if-let* 块,类似于clojuredocs.org/clojure.core/…
    【解决方案2】:

    if-let 的一个很好的用例是消除使用回指的需要。例如,Arc 编程语言提供了一个名为aif 的宏,当给定表达式的计算结果为逻辑真时,它允许您在if 表单的主体内绑定一个名为it 的特殊变量。我们可以在 Clojure 中创建相同的东西:

    (defmacro aif [expr & body]
      `(let [~'it ~expr] (if ~'it (do ~@body))))
    
    (aif 42 (println it))
    ; 42
    

    这很好,除了回指不嵌套,但if-let 这样做:

    (aif 42 (aif 38 [it it]))
    ;=> [38 38]
    
    (aif 42 [it (aif 38 it)])
    ;=> [42 38]
    
    (if-let [x 42] (if-let [y 38] [x y]))
    ;=> [42 38]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-06-04
      • 2015-10-18
      • 1970-01-01
      • 1970-01-01
      • 2018-09-16
      • 2015-03-24
      • 2015-08-26
      • 2010-10-07
      相关资源
      最近更新 更多