请在2024 年 Clojure 状态调查中分享您的想法!

欢迎!请参阅关于页面,了解更多关于此页如何工作的信息。

0
Java 互操作
编辑

我想将此 Java 代码转换为 Clojure

S3Client.builder()
      .serviceConfiguration(S3Configuration.builder()
            .pathStyleAccessEnabled(true)
            .build())
      .build();

问题:《.serviceConfiguration》需要一个 java.util.function.Consumer

default B serviceConfiguration(Consumer<S3Configuration.Builder> serviceConfiguration)

.serviceConfiguration 方法定义在这里 AWS SDK serviceConfiguration

我试着使用 reify,但没有什么运气。

也许有人可以指明正确的方向,或者已经使用过这个 API 的特定部分。

有人能告诉我,这种 API 设计方式对 Java 开发者有什么优势,这种构造有什么作用吗?

1 个答案

0

被选中
 
最佳答案

考虑到 Java 代码,第三行的 .build() 方法也必须返回一个 Consumer 实例。因此,不需要重新实例化 anything,你应该可以这样做

(let [consumer (-> (S3Configuration/builder) (.pathStyleAccessEnabled true) (.build))]
  (-> (S3Client/builder) (.seviceConfiguration consumer) (.build)))

这种模式,您创建一个构建器,在其上调用许多配置方法,然后调用.build获得您真正需要的最终对象,被称为... "构建器"。 :) 在面向对象的世界里,当您想要确保封装性且没有任何部分构建的对象时,它非常有帮助。它还可以帮助在某些情况下,您需要使用不同的构建器来使用相同的接口以不同方式行为。或者,如果您不得不在不同的上下文中分开创建对象。

感谢您的回答。这也是我的第一个方法。

但是运行上面这个代码示例导致以下异常

```
; (err) 执行错误 (ClassCastException) 在 java.lang.Class/cast (Class.java:3889)。
; (err) 无法将 software.amazon.awssdk.services.s3.S3Configuration 强制转换为 java.util.function.Consumer
```

这就是为什么我尝试使用reify的原因

为了澄清:我在想,他们为什么需要在方法中用一个Consumer,这个签名的目的是什么
`(Consumer<S3Configuration.Builder> serviceConfiguration)`

感谢您花时间。
我明白了。将错误放入原始帖子中通常很有帮助。 ;) `serviceConfiguration`方法有两个签名 - 一个接受`Consumer`的实例,另一个接受`S3Configuration`的实例。您可以尝试通过使用`(.serviceConfiguration ^S3Configuration consumer)`来诱导Clojure编译器使用第二个签名。

关于您的"有什么用处"问题 - 我认为这取决于AWS JDK本身,而不是Java本身。
添加类型提示有效。感谢!

出于好奇,是否有简单的方法创建一个Consumer?
这些是截然不同的接口,所以没有直接的方法。但您可以使用`reify`创建一个实现`Consumer`的对象,也许可以在那里使用配置。
...