Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在clojure中,如何调用x的所有方法,然后返回最后一次表单执行的值?_Clojure - Fatal编程技术网

在clojure中,如何调用x的所有方法,然后返回最后一次表单执行的值?

在clojure中,如何调用x的所有方法,然后返回最后一次表单执行的值?,clojure,Clojure,我正在寻找类似于doto的内容,但我希望返回上次调用的值,而不是返回x 例如,而不是: (.size (doto (java.util.ArrayList.) (.add 2) (.add 3))) 我想写: (mydoto (java.util.ArrayList.) (.add 2) (.add 3) .size) 实现此结果的惯用方法是什么?doto返回

我正在寻找类似于
doto
的内容,但我希望返回上次调用的值,而不是返回
x

例如,而不是:

(.size (doto (java.util.ArrayList.) 
             (.add 2)
             (.add 3)))
我想写:

(mydoto (java.util.ArrayList.) 
             (.add 2)
             (.add 3)
             .size)

实现此结果的惯用方法是什么?

doto
返回它的第一个参数
->
->
返回计算最后一个表单的结果(在遍历第一个表达式后,请参见
(clojure.repl/doc->)
。宏
doto
将按如下方式展开代码:

(let [r (java.util.ArrayList.)]
  (.add r 2)
  (.add r 3)
  r)
当您使用
.size
时,它不会影响数组列表,您只对方法的返回值感兴趣(与
.add
不同,后者返回布尔值并更改您感兴趣的ArrayList的状态)

您不能像在mydoto中那样混合使用这些方法,因为您需要的是不同类型的返回值和输入值。如果您想将最终大小乘以3,这将是惯用的:

(-> (doto (java.util.ArrayList.) 
          (.add 2)
          (.add 3))
    .size
    (* 3))
甚至

(-> (java.util.ArrayList.)
    (doto (.add 2) (.add 3))
    .size
    (* 3))

这些宏应该使代码更易于阅读,因此根据上下文,我将以最有意义的方式编写它们。

Clojure宏将允许您做您想做的事情,事实上,对现有的doto宏只需1个符号的更改(在emacs中使用Meta-。查看core.clj中的定义)

这将允许您编写以下代码:

(mydoto (java.util.ArrayList.) 
         (.add 2)
         (.add 3)
         .size)
;; => 2

可以使用
doto
编写
mydoto
,如@lgrapenthin所述:

(defmacro mydoto 
    "Like doto but returns the result of the last form instead 
     of the first argument"
    [& args]
    `(-> (doto ~@(butlast args))
         ~(last args)))

非常好!谢谢@user499049编写这样的宏来实现OP想要的东西不是惯用的,只是混淆了他正在使用的源代码。它也可以用现有代码写成一行代码:(defmacro my doto[&args]`(->(doto~@(butlast args))~(last args))@lgrapenthin你应该自己写一个答案
(defmacro mydoto 
    "Like doto but returns the result of the last form instead 
     of the first argument"
    [& args]
    `(-> (doto ~@(butlast args))
         ~(last args)))