使用Clojure,如何创建以下对象?该对象取自java代码(From Effective Java):
NutritionFacts cocaCola =
new NutritionFacts.Builder(240,8).calories(100).sodium(35).carbohydrate(27).build();
答案 0 :(得分:23)
虽然很难与其他答案 1 中的简洁性争论,..
有点失宠,取而代之的是更多才多艺的->
。我个人更喜欢:
(-> (NutritionFacts$Builder. 240 8)
(.calories 100)
(.sodium 350)
(.carbohydrates 27)
(.build))
这是另外两个角色,但你获得了两件事:
.
就在那里。最重要的是,这个问题的每个其他答案都让错误的类名:Java的NutritionFacts.Builder是名为NutritionFacts $ Builder的真正JVM类的语言糖,而那个类是Clojure必须引用的类(因为我们不是使用javac编译我们的代码)。
1 我不同意doto
建议:它的作用只是因为这个Builder类碰巧通过改变单个实例然后返回它来实现其方法链。 doto
非常适合需要就地变异的Java对象,但是当一个类足够假装它是不可变的时,你应该真正使用方法链接版本(即->
)。
答案 1 :(得分:8)
使用..宏。这是两个连续的点。它只允许你需要的东西 - 连续调用前一个结果的下一个Java方法。
我没有REPL,但你的行应该转换为:
(.. (NutritionFacts.Builder. 240 8)
(calories 100)
(sodium 350)
(carbohydrates 27)
(build))
答案 2 :(得分:3)
我只是从Clojure开始,但它看起来像是对我的标准方法调用:
(doto
(NutritionFacts.Builder. 240 8)
(.carbohydrates 27)
(.sodium 35)
(.calories 100)
(.build)
)
编辑:
正如@Goran Jovic指出的那样,这会调用以第一种形式创建的对象上的所有方法
因此,它适用于这种情况,因为Java代码使用方法链接,但通常不适用。
答案 3 :(得分:2)
(.. (NutrionalFacts.Builder. 240 8) (calories 100) (sodium 35) (carbohydrates 27) (build))
答案 4 :(得分:1)
这个线程已经有几年了,据我所知,线程优先宏仍然是首选方式,但不需要$语法。 斜杠(/)也起作用:
{{1}}