如何将双冒号运算符翻译成Clojure?

6

我在阅读一个我正在尝试掌握的框架的源代码时,发现了Java 8的新语法:

 Runtime.getRuntime().addShutdownHook(new Thread(Sirius::stop));

在Clojure中,我可以将其翻译为:
(.addShutdownHook (Runtime/getRuntime) (Thread. ????))

但我不确定???应该填什么。



1
可能是重复的问题:如何在Clojure中调用Java静态方法? - Havenard
1
你是认真的吗?我看了一下答案,它们并没有回答我需要在“???”中放什么。 - zcaudate
双冒号 = 静态方法。 - Havenard
2
(Thread. #(Sirius/stop)) 应该可以工作,它只是一个静态方法。 - noisesmith
3
@Havenard,双冒号并不意味着静态方法。它是Java 8方法句柄(在这种情况下指向静态方法)。方法句柄(类似于函数指针)意味着您可以提供一个在以后调用的方法(在此示例中为调用Thread.start()时)。 - Mark Rotteveel
显示剩余2条评论
2个回答

4

IFn扩展了Runnable接口,因此你只需要执行:

#(Sirius/stop)

值得注意的是:
  • 你需要创建lambda表达式。Clojure不允许你仅使用
  • Java 8函数式接口在底层通过实现仅有一个方法的接口来创建匿名实现。所以

    new Thread(Sirius::stop)

只是语法糖而已。

new Thread(new Runnable {
    public void run() {
        Sirius.stop();
    }
})

如果所涉及的接口不是Runnable/Callable,则必须使用reify宏。

2
@zcaudate 你能给我点赞/标记为正确吗?谢谢! - George Simms

2

@george-simms的解释是正确的,但对于那些寻找不是Runnable/Callable示例并需要使用reify的人,这里有一个例子。

假设您想要像这样使用DateTimeFormatter parse方法:


DateTimeFormatter dtf = DateTimeFormatter.ISO_LOCAL_DATE();
LocalDate d = dtf.parse("2019-04-04", LocalDate::from);

您需要检查parse的第二个参数的功能接口类型,我们的情况下是TemporalQuery。这意味着您需要实例化TemporalQuery并实现其唯一方法(功能接口始终只有一个方法),以便调用LocalDate类上的静态方法from。因此,在Clojure中它也会被翻译成:

(import 'java.time.format.DateTimeFormatter)
(import 'java.time.temporal.TemporalQuery)
(import 'java.time.LocalDate)

(let [dtf (DateTimeFormatter/ISO_LOCAL_DATE)]
  (.parse dtf "2019-04-04"
          (reify TemporalQuery
                 (queryFrom [this temporal]
                            (LocalDate/from temporal)))))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接