在 clojure 中处理 Java 可选 <T>
Dealing with Java Optional<T> in clojure
我正在编写与外部 Java 库交互的 Clojure 代码。 returns Java Optional
对象的方法之一。假设它 returns Optional<String>
并且我需要将 Optional
对象中的字符串值更改为小写。如果我在 Java:
中编写代码,我会使用 map
方法
Optional<String> ret = someObj.someMethod();
ret.map(String::toLowerCase)
.map(...)
.orElse("x");
因此,我需要在 Clojure 中调用 someObj.someMethod()
并且必须执行类似的工作。我发现的是:
所以我写了这样的代码:
(defn ^java.util.function.Function jfn [f]
(reify java.util.function.Function
(apply [this arg] (f arg))))
(let [ret (.someMethod someObj)]
(.. ret
(map (jfn (fn [x] (s/lower-case x))))
(map (jfn (...)))
(orElse "x")))
为了将 clojure 函数传递到需要 Java lambda 的地方,我使用了 jfn
定义如上。实际上它工作正常。
但我不确定这是最好的方法,因为我必须用 Java 的 Function
包装调用 Java 方法的 clojure 函数。
有什么better/simpler方法可以做到这一点吗?如果能直接调用JavaString
的toLowerCase
方法就更好了。
我不确定它是否适合你的用例,但你可以在早期 "unbox" Optional
,然后使用 some->
宏进行类似的短路-空函数组合。
即使您以后需要 Optional
和值,提前拆箱并稍后重新装箱可能比 Function
互操作更容易。
(defn optional->nilable [this]
(when (.isPresent this)
(.get this)))
(def maybe (Optional/of " something "))
(some-> (optional->nilable maybe)
(clojure.string/trim)
(not-empty)
(clojure.string/upper-case))
; => "SOMETHING"
然后如果你需要转换回 Optional
:
(Optional/ofNullable *1)
我正在编写与外部 Java 库交互的 Clojure 代码。 returns Java Optional
对象的方法之一。假设它 returns Optional<String>
并且我需要将 Optional
对象中的字符串值更改为小写。如果我在 Java:
map
方法
Optional<String> ret = someObj.someMethod();
ret.map(String::toLowerCase)
.map(...)
.orElse("x");
因此,我需要在 Clojure 中调用 someObj.someMethod()
并且必须执行类似的工作。我发现的是:
所以我写了这样的代码:
(defn ^java.util.function.Function jfn [f]
(reify java.util.function.Function
(apply [this arg] (f arg))))
(let [ret (.someMethod someObj)]
(.. ret
(map (jfn (fn [x] (s/lower-case x))))
(map (jfn (...)))
(orElse "x")))
为了将 clojure 函数传递到需要 Java lambda 的地方,我使用了 jfn
定义如上。实际上它工作正常。
但我不确定这是最好的方法,因为我必须用 Java 的 Function
包装调用 Java 方法的 clojure 函数。
有什么better/simpler方法可以做到这一点吗?如果能直接调用JavaString
的toLowerCase
方法就更好了。
我不确定它是否适合你的用例,但你可以在早期 "unbox" Optional
,然后使用 some->
宏进行类似的短路-空函数组合。
即使您以后需要 Optional
和值,提前拆箱并稍后重新装箱可能比 Function
互操作更容易。
(defn optional->nilable [this]
(when (.isPresent this)
(.get this)))
(def maybe (Optional/of " something "))
(some-> (optional->nilable maybe)
(clojure.string/trim)
(not-empty)
(clojure.string/upper-case))
; => "SOMETHING"
然后如果你需要转换回 Optional
:
(Optional/ofNullable *1)