Clojure doto宏

4 java clojure

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

(doto (java.lang.String. "clojure")
       (.toUpperCase))
Run Code Online (Sandbox Code Playgroud)

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

lee*_*eor 5

文档:

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

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

  • @AmirTeymuri我使用`doto`和可变的Java对象,需要在instanciation之后修改:`(doto(Widget.)(setVisible t)(setParent frame))`或其他副作用,如打印. (2认同)

Art*_*ldt 5

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

Foo foo = new Foo;
foo.setX().setY().makeFactory().applyPhaseOfMoon();
Run Code Online (Sandbox Code Playgroud)

有8个parens成为:

(doto foo .setY .makeFactory .applyPhaseOfMoon)
Run Code Online (Sandbox Code Playgroud)

共有两个.

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

user> (doto "hi" .toUpperCase)
"hi"
Run Code Online (Sandbox Code Playgroud)

扩展为:

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

第二行执行此操作:

user> (.toUpperCase "hi")
"HI"
Run Code Online (Sandbox Code Playgroud)

然后抛出答案并从开始返回保存的值.我个人从来没有看到doto在人们将java翻译为clojure的地方之外的实践,以便调用一些API.


omi*_*iel 5

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

扩展为第一个参数的第一个成员的成员访问 (.),然后是结果的下一个成员,依此类推。例如:

(.. System (getProperties) (get "os.name"))
Run Code Online (Sandbox Code Playgroud)

扩展为:

(. (. System (getProperties)) (get "os.name"))
Run Code Online (Sandbox Code Playgroud)

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

在你的情况下:

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

(.. "clojure" toUpperCase)
; => "CLOJURE"
Run Code Online (Sandbox Code Playgroud)