6

我正在尝试在风暴服务器上部署拓扑,它不断告诉我以下信息:

java.lang.RuntimeException: java.lang.IllegalStateException: Attempting to call unbound fn: #'storm-nblabla/operation-bolt__ at backtype.storm.clojure.ClojureBolt.prepare(ClojureBolt.java:60) a

所以我想我必须绑定一个我在准备函数中使用的函数。所以我的问题是你通常如何在 clojure 中绑定函数?

问候,

贺拉斯

4

1 回答 1

12

在 clojure 中,一个值通常以以下两种方式之一进行绑定:

  • locals,没有命名空间限定符,(通常在let语句或fn/ loopargs 中)
    这是针对未在块范围之外引用的值(除非它们作为参数提供给块内或返回中的函数块的价值)。

  • vars,具有命名空间范围,通常使用def (或类似的辅助宏defn
    这是用于应在命名空间范围内访问的值,无论您可以访问命名空间的任何地方都可以访问这些值。

错误(试图调用未绑定的 fn)是由使用declare创建一个 var,然后在没有提供真实定义的情况下调用它引起的:

user> (declare foo)
#'user/foo
user> (foo)
IllegalStateException Attempting to call unbound fn: #'user/foo  clojure.lang.Var$Unbound.throwArity (Var.java:43)

在此代码中, var 存在(declare创建它),但没有分配任何值。所以你需要后一种绑定,一个 var 绑定:

user> (defn foo [] "OK")
#'user/foo
user> (foo)
"OK"
user> 

在某个地方,您的代码的某些部分或您正在使用的库的代码声明了一个 var,它应该绑定到一个可调用的值,但尚未正确初始化。该库是否具有init某种您尚未调用的功能?也许在定义可见之前您需要一个命名空间?

于 2013-10-25T14:55:43.867 回答