如何在clojure中创建静态成员

时间:2014-04-21 15:30:07

标签: clojure static

我有一个类(由deftype创建),我想要对它进行反序列化等几个静态成员。我试图在界面中添加他们的签名,但它对我有用(下面的代码)。

(definterface INmk
  (serialize [])
  (deserialize [string])
  (print []))

(deftype NmkLinear [^:volatile-mutable a
                    ^:volatile-mutable b
                    ^:volatile-mutable x-sum
                    ^:volatile-mutable y-sum
                    ^:volatile-mutable xy-sum
                    ^:volatile-mutable xq-sum
                    ^:volatile-mutable n]  
  INmk
  (serialize [this]
    (str "{\"a\":" a
         " \"b\":" b
         " \"x-sum\":" x-sum
         " \"y-sum\":" y-sum
         " \"xy-sum\":" xy-sum
         " \"xq-sum\":" xq-sum
         " \"n\":" n
         "}"))

  (deserialize [str]
    (let [j (json/read-str str :key-fn keyword)]
      (NmkLinear.
       (:a j) (:b j) (:x-sum j) (:y-sum j) (:xy-sum j) (:xq-sum j) (:n j))))

2 个答案:

答案 0 :(得分:2)

如果由于某种原因你真的需要静态方法,那么你需要回归到gen-class。

http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/gen-class

这允许您使用适当的元数据注释方法,以指定它们应该是静态的。

^{:static true}

正如内森所说,静态成员不适用于接口。

答案 1 :(得分:1)

Java中的接口不允许在它们上定义静态方法;允许的唯一静态成员是常量(其中您创建的任何字段都假定为静态和最终),Java Language Specification表示,"访问修饰符静态仅适用于成员接口"。如果Java无法做到这一点,那么Clojure的definterface当然也不能。

静态方法不是多态的,因此在接口上定义它们无论如何都不会有用。将反序列化等事物改为独立函数(或以其他方式寻找组织它的不同方法)。

编辑:从Java 8开始,您可以向界面添加静态方法,因此上述大多数都是过时的。 (另外我不清楚Clojure是否支持这个。)从你的例子看来,这实际上并不是你想要的。如果将其添加到接口,则接口的所有实现的方法实现都是相同的。