Java调用Clojure函数时如何处理不同的返回类型?

use*_*344 2 java interop clojure

我想binomial从 Java 调用 Clojure 函数。我遇到的一个问题是它返回不同的数据类型,或者long(例如,n=5,k=3)或BigInt(例如,n=20,k=10)。在Java方面,它应该是一个BigInteger。

至少有两种选择可以克服这个问题,哪一个更好?

  1. 强制 Clojure 函数返回 BigInt (我不知道这是否可能。我尝试了类型提示,但它仍然返回longor BigInt)。
  2. 在Java中,对返回值使用模式匹配并检查类型,然后进行适当的转换。

克洛尤尔

(ns sample.hello
  (:import (clojure.lang BigInt)))

(defn binomial
      "Calculate the binomial coefficient."
      ^BigInt [^Integer n ^Integer k]
      (let [a (inc n)]
           (loop [b 1
                  c 1]
                 (if (> b k)
                   c
                   (recur (inc b) (* (/ (- a b) b) c))))))
Run Code Online (Sandbox Code Playgroud)

爪哇

public class Hello {
    public static final IFn binomial;

    static {
        Clojure.var("clojure.core", "require").invoke(Clojure.read("sample.hello"));
        binomial = Clojure.var("sample.hello", "binomial");
    }

    public static BigInteger binomial(int n, int k) {
        Object a = binomial.invoke(n, k);
        return ((BigInt) a).toBigInteger();
    }
}
Run Code Online (Sandbox Code Playgroud)

Mar*_*ůda 5

您还可以使用该函数biginteger强制 Clojure 返回java.math.BigInteger(并避免在 Java 中进行转换):

(defn binomial
  "Calculate the binomial coefficient."
  [^Integer n ^Integer k]
  (let [a (inc n)]
    (loop [b 1
           c 1]
      (if (> b k)
        (biginteger c)
        (recur (inc b) (* (/ (- a b) b) c))))))
Run Code Online (Sandbox Code Playgroud)

测试:

(class (binomial 5 3))
=> java.math.BigInteger
(class (binomial 20 10))
=> java.math.BigInteger
Run Code Online (Sandbox Code Playgroud)