请在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 的实例。因此,无需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` 的对象,并在那里使用配置。
...