Clojure doto宏

时间:2015-10-02 21:09:29

标签: java clojure

我将在.toUpperCase宏中调用doto方法,如下所示,但doto返回小写字母:

(doto (java.lang.String. "clojure")
       (.toUpperCase))

返回" clojure"。我做宏扩展,因为返回值是创建的对象: (clojure.core/let [G__7359 (java.lang.String. "cojure")] (.toUpperCase G__7359) G__7359) ,但为什么我不能得到大写的回答?

3 个答案:

答案 0 :(得分:5)

来自documentation

  

评估x然后使用值调用所有方法和函数   在给定参数的前面提供的x。表格是   按顺序评估。 返回x。

doto返回原始参数,而不是使用它执行的函数的任何结果。我相信doto函数通常用于副作用。这就是你得到原始字符串的原因。

答案 1 :(得分:5)

doto是Clojure的Java互操作功能的一部分。它的设计目的是为了能够编写java而不需要很多parens。所以

Foo foo = new Foo;
foo.setX().setY().makeFactory().applyPhaseOfMoon();

有8个parens变成:

(doto foo .setY .makeFactory .applyPhaseOfMoon)

总共有两个。

在这种情况下,如果我们深入研究你的例子的扩展:

user> (doto "hi" .toUpperCase)
"hi"

扩展为:

user> (macroexpand-1 '(doto "hi" .toUpperCase))
(clojure.core/let [G__110453 "hi"]
   (.toUpperCase G__110453) 
   G__110453)

第二行执行此操作:

user> (.toUpperCase "hi")
"HI"

然后抛出答案并从开头返回保存的值。我个人从来没有看到doto在实践中用于人们正在将java翻译为clojure以便调用某些API的地方。

答案 2 :(得分:4)

您要找的是..线程宏(https://clojuredocs.org/clojure.core/_..):

  

扩展为第一个成员的成员访问(。)   参数,然后是结果的下一个成员,等等   实例:

(.. System (getProperties) (get "os.name"))
     

扩展为:

(. (. System (getProperties)) (get "os.name"))
     

但更容易编写,阅读和理解。

在你的情况下:

(doto "clojure" .toUpperCase)
; => "clojure"

(.. "clojure" toUpperCase)
; => "CLOJURE"