如何创建一个忽略任何参数并始终抛出异常的函数?

Dan*_*oss 1 clojure

(constantly (throw (Exception. "Don't call me")))基于Clojure 文档,我希望如何做到这一点constantly:

(constantly x)

返回一个函数,它接受任意数量的参数并返回x.

但是当我尝试不断创建一个总是抛出的模拟函数时,会立即抛出异常,我试图定义函数.是constantly应该评估它的机身向右走,并缓存结果呢?我是否遇到了相当于C的可怕的未定义行为(在这种情况下,"一旦你依赖副作用,所有的赌注都会被取消")?

user=> (constantly (throw (Exception. "but not right now")))

Exception but not right now  user/eval8734 (form-init1747541642059004341.clj:1)
user=> (repeatedly (throw (Exception. "but not right now")))

Exception but not right now  user/eval8736 (form-init1747541642059004341.clj:1)
Run Code Online (Sandbox Code Playgroud)

在测试中创建模拟回调函数的惯用方法是什么,以便在调用时抛出错误?

Sam*_*tep 6

constantly是一个功能; 它评估其参数,然后返回一个将返回该评估结果的函数.如果你想编写一个忽略其所有参数并在每次调用时计算某个表达式的函数,你可以这样做:

(fn [& _] (throw (Exception. "Don't call me")))
Run Code Online (Sandbox Code Playgroud)

例:

((fn [& _] (throw (Exception. "Don't call me"))) :foo :bar)
;=> java.lang.Exception: Don't call me
Run Code Online (Sandbox Code Playgroud)

您还可以编写一个宏来创建忽略其参数的函数:

(defmacro ignore-args [& exprs]
  `(fn ~'[& _] ~@exprs))
Run Code Online (Sandbox Code Playgroud)

例:

((ignore-args (throw (Exception. "Don't call me"))) :foo :bar)
;=> java.lang.Exception: Don't call me
Run Code Online (Sandbox Code Playgroud)

但是,我并不完全确定这样的宏有多么有用,因为任何类型的描述性名称(ignore-args在这种情况下)都需要更长的时间来输入,(fn [& _] ,,,)而不是真正传达更多的语义含义.