Clojure中-toString与.toString的区别

时间:2014-01-27 21:53:01

标签: java clojure

根据The Anatomy of gen-class中对:gen-class的说明,我使用leiningen来获取类文件。

  1. leon new pinger创建项目。
  2. cd srcmkdir some并在其中创建了一个Example.clj文件。
  3. :aot [some.Example]
  4. 中添加了:aot :all(或project.clj

    Example.clj如下:

    (ns some.Example
      (:gen-class))
    
    (defn -toString
      [this]
      "Hello, World!")
    

    然后我执行lein compile以获取target目录中的类。

    然后,我用lein repl执行此代码。

    (-toString (some.Example.)) ; should return "Hello, World!"
    

    但是,我收到此错误消息。

    CompilerException java.lang.RuntimeException: Unable to resolve symbol: 
    -toString in this context, compiling:(/private/var/folders/nw/dmb7jh3d2hq89296z2gnntqm0000gn/T/form-
    init7145760420048735997.clj:1:1) 
    

    .toString运行正常。

    user=> (.toString (some.Example.))
    "Hello, World!"
    

    该网站解释说,我应该从-toString.toString获得相同的结果,但我只得到.toString的正确结果。

    Clojure中-toString.toString之间有什么区别?为什么-toString会在示例中引发错误?

1 个答案:

答案 0 :(得分:7)

首先,一些术语:

  1. (.toString (some.Example.))是对新构建的toString实例的some.Example方法的调用。

  2. (-toString (some.Example.))是一个常规的Clojure函数调用,-toString是存储函数的Clojure Var的名称,而(some.Example.)是其唯一参数。

    < / LI>

    :gen-class安排事情,以便-toString Var支持toString方法;也就是说,对toString实例的some.Example方法的任何调用都会导致对-toString的调用。所以确实只是直接调用-toString是等效的。

    但是,在通过引用存储它的Var调用Clojure函数之前,需要确保已经加载了这个Var所在的命名空间(这里没有问题,因为你能够构造some.Example)的实例,然后通过其完全限定名称引用Var,或者使用referuserequirealias来可以用更短的名称来引用它:

    (some.Example/-toString ...)
    
    (use '[some.Example :only [-toString]])
    (-toString ...)
    
    (require '[some.Example :refer [-toString]])
    (-toString ...)
    
    (require '[some.Example :as se])
    (se/-toString ...)
    
    ;; refer and alias are typically not used directly
    

    如果您在没有先使用{sup> 1 所示的-toStringreferuse的情况下说require,Clojure将尝试解析该符号-toString到当前命名空间中的Var(在REPL会话中通常为user;对于lein repl,它可能是:main表单中的defproject命名空间。 / p>


    1 那是关于REPL的。在源文件中,您通常会在:use表单中使用:requirens;语法与use / require减去引号相同。