【发布时间】:2017-07-12 23:35:46
【问题描述】:
在 Python 中,我可以执行以下操作:
fast_thing_available = True
try:
import fast_thing
except ImportError:
fast_thing_available = False
# snip
if fast_thing_available:
default = fast_thing
else:
default = slow_thing
是否可以在 Clojure 中做同样的事情? 我尝试了下一个,但它失败了(例如仍然需要导入):
(ns sample.ns)
(def ^:private long-adder-available (atom false))
(try
(do
(import 'java.util.concurrent.atomic.LongAdder)
(swap! long-adder-available (constantly true)))
(catch ClassNotFoundException e ()))
(when (true? @long-adder-available)
(do
; Here I'm using LongAdder itself
))
即使LongAdder 本身不可用,代码也会抛出IllegalArgumentException: unable to resolve classname: LongAdder。
【问题讨论】:
-
所以你开始一个repl,你输入
(import 'java.util.concurrent.NotAClass),你得到一个IllegalArgumentException?您的代码按我的预期工作。ClassNotFoundException被抓到了。 -
另外注意,你的
swap!形式可以更好地表达为:(reset! long-adder-available true),你也可以更简洁地表达你的when:(when @long-adder-available ...),并且在@987654332 下@ 和when,你不需要do -
@Josh 我不同意您认为它按预期工作的评估。重要的不是
import表达式在运行时引发的ClassNotFoundException,而是when中的代码在编译时引发的异常,无论它是否实际运行都会被编译。 -
@amalloy 哎呀!当我运行该示例时,我完全忘记了将类的用法实际放在
when块中。感谢您的捕获!你的结论是发帖人想要做的事情是不可能的吗? -
并非不可能,但它很粗糙、很难,而且通常不是 Clojure 中的工作方式。您基本上必须使用反射而不是正常引用该类。
标签: clojure