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

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

0
Java互操作
编辑

我想将这段Java代码转换为Clojure

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

问题:`seviceConfiguration` 方法需要 java.util.function.Consumer

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

`servcieConfiguration` 方法在这里定义:[AWS SDK 中的 serviceConfiguration](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/S3BaseClientBuilder.html#serviceConfiguration(java.util.function.Consumer))

我尝试使用 `reify`,但没有取得太多成功。

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

有人能告诉我为什么这种API设计对Java开发者来说是有利的吗?这种构造的目的是什么?

1 个答案

0

选择
 
最佳答案

考虑到Java代码,第三行的 .build() 方法也必须返回一个 Consumer 实例。因此无需使用 `reify`,您应该可以这样使用

(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`的对象,也许可以在那里使用配置。
...