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

我尝试了使用 `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` 实例。你可以尝试让 Clojure 编译器使用第二个签名,通过使用 `(.serviceConfiguration ^S3Configuration consumer)`。

关于你的 “意义何在” 问题 — 我也不知道,因为这个问题是关于 AWS JDK,而不是关于 Java 的一般情况。
类型提示确实有效。谢谢!

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