简体   繁体   English

Clojure中-toString与.toString的区别

[英]The difference between -toString vs .toString in Clojure

Following the explanation about :gen-class in The Anatomy of gen-class , I used leiningen to get the class files. 在关于:gen-class Anatomy的gen-class的解释之后,我使用leiningen来获取类文件。

  1. leon new pinger to create a project. leon new pinger创建一个项目。
  2. cd src and mkdir some and created a Example.clj file in it. cd srcmkdir some并在mkdir some创建了一个Example.clj文件。
  3. Added :aot [some.Example] (or :aot :all ) in project.clj . project.clj添加了:aot [some.Example] (或:aot :all )。

The Example.clj is as follows: Example.clj如下:

(ns some.Example
  (:gen-class))

(defn -toString
  [this]
  "Hello, World!")

Then I executed lein compile to get the classes in target directory. 然后我执行lein compile以获取target目录中的类。

Then, I was executing this code with lein repl . 然后,我用lein repl执行这段代码。

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

However, I got this error message. 但是,我收到此错误消息。

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 works fine. .toString工作正常。

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

The website explains that I should get the same results from both -toString and .toString , but I got only correct results with .toString . 该网站解释说我应该从-toString.toString获得相同的结果,但我只得到.toString正确结果。

What's the difference between -toString and .toString in Clojure? Clojure中-toString.toString什么区别? Why -toString raises an error in the example? 为什么-toString会在示例中引发错误?

First, some terminology: 首先,一些术语:

  1. (.toString (some.Example.)) is a call to the toString method of the newly constructed some.Example instance. (.toString (some.Example.))是对新构造的some.Example实例的toString方法的调用。

  2. (-toString (some.Example.)) is a regular Clojure function call, with -toString being the name of a Clojure Var storing a function and (some.Example.) being its sole argument. (-toString (some.Example.))是一个常规的Clojure函数调用, -toString是存储函数的Clojure Var的名称,而(some.Example.)是它的唯一参数。

:gen-class arranges things so that the -toString Var backs the toString method; :gen-class排列事物,以便-toString Var支持toString方法; that is, any call to the toString method of a some.Example instance results in a call to -toString . 也就是说,对some.Example实例的toString方法的任何调用some.Example导致对-toString的调用。 So it is indeed the case that just calling -toString directly is equivalent. 所以确实只是直接调用-toString是等效的。

However, before you can call a Clojure function by referring to the Var in which it's stored, you need to make sure the namespace in which this Var lives has been loaded (not a problem here, given that you were able to construct an instance of some.Example ) and then either refer to the Var by its fully-qualified name, or else use refer , use , require or alias to make it possible to refer to it by a shorter name: 但是,在通过引用存储它的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

If you say -toString without first using refer , use or require as shown above 1 , Clojure will attempt to resolve the symbol -toString to a Var in the current namespace (typically user in REPL sessions; with lein repl it may be the :main namespace from your defproject form). 如果你说-toString没有首先使用referuse或者require如上所示1 ,Clojure将尝试将符号-toString解析为当前命名空间中的Var(通常是REPL会话中的user ;使用lein repl它可能是:main您的defproject表单中的命名空间)。


1 That's speaking about the REPL. 1这是关于REPL的。 In a source file, you'd typically use :use or :require in your ns form; 在源文件中,您通常在ns表单中使用:use:require ; the syntax is the same as for use / require minus the quoting. 语法与use / require减去引用相同。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM