代码之家  ›  专栏  ›  技术社区  ›  Joe

Clojure是否有一个在调用时执行身体功能的“持续”形式?

  •  1
  • Joe  · 技术社区  · 6 年前

    constantly 在对引发异常的场景建模的测试中。不断地使用现成的方法,在读取代码而不是执行代码时对主体进行求值。我不能这么做:

    (def x (constantly (throw (Exception. "X"))))
    (x 1 2 3)
    

    取而代之的是 throw 立即发生。

    这样做有效:

    (defn x [&] (throw (Exception. "X")))
    

    但是 不断地 是如此的方便和惯用,我想知道是否有一个内置的等价物可以做到这一点,也许使用一个宏?

    4 回复  |  直到 6 年前
        1
  •  3
  •   tap    6 年前

    一种选择

    #(throw (Exception. (str %&)))
    
        2
  •  1
  •   Ertuğrul Çetin    6 年前

    不断地 是一个 功能 不是一个 喜欢 fn 所以你需要使用 (fn [& args]) 实现这种操作。

    急切地评估它的参数,这就是它立即失败的原因。

        3
  •  1
  •   Thumbnail    6 年前

    它不是内置的,但是很容易定义。我们就叫它吧 defer :

    (defmacro defer [exp]
      (list 'fn ['& '_] exp))
    

    你的例子变成

    (def x (defer (throw (Exception. "X"))))
    => #'user/x
    
    (x 1 2 3)
    => Exception X  user/x (form-init7339591407440568822.clj:10)
    

    这与使用 # reader form tap 是的,但这是你要求的。


    thunk .

        4
  •  0
  •   nha    6 年前

    Clojure中有几种延迟计算的方法

    delay :

    (def x (delay (throw (ex-info "myException" {}))))
    @x ;; exception is thrown
    

    您还可以使用lambda,类似于在其他语言中必须执行的操作,或者使用lazness。

    考虑到问题中的代码示例,您似乎在寻找以下内容:

    (defn x [& args]
      (throw (ex-info "myException" {:args args})))
    
    (try
      (x 1 2 3)
      (catch Exception e
        (println "Exception! data is "  (ex-data e))))
    

    注意使用 ex-info ex-data 可以用来传递信息。