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 实例。因此无需重新实例化,您应该能够使用此方法

(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` 的对象,并可能以某种方式在那里使用配置。
...