Clojure/Scala互操作?

6

我试图将这个简单的Scala代码与其他程序进行互操作,但遇到了一些问题。

package indicators

class DoubleRingBuffer(val capacity:Int=1000) {
  var elements = new Array[Double](capacity);
  private var head=capacity-1
  private var max=0

  def size ():Int = {
    return max+1
  }

  def add(obj:Double):Double = {
    head-=1
    if (head<0) head=capacity-1
    return set(max+1,obj)
  }

  def set(i:Int,obj:Double):Double = {
    System.out.println("HI")
    if (i>=capacity || i<0)
      throw new IndexOutOfBoundsException(i+" out of bounds")
    if (i>=max) max=i
    var index = (head+i)%capacity
    var prev = elements(index)
    elements(index)=obj
    return prev
  }

  def get(i:Int=0):Double = {
    System.out.println("size is "+size())
    if (i>=size() || i<0)
      throw new IndexOutOfBoundsException(i+" out of bounds")
    var index = (head+i)%capacity
    return elements(index)
  }    
}

在Clojure中,我会这样做。
(import 'indicators.DoubleRingBuffer)
(def b (DoubleRingBuffer. 100))
(pr (.size b)) ;;ERROR: No matching field found: size for class indicators.DoubleRingBuffer
(pr (.get b 33)) ;;returns 0: should throw an index out of bounds error!
(pr (.get b 100)) ;;throws index out of bounds error, as it should

此外,我没有在控制台上得到任何输出!使用scala测试此代码的结果与预期相符。这里出了什么问题,我该如何修复,以便clojure可以使用scala代码?
1个回答

9

在REPL中尝试以下内容:

(class b) 可能会告诉你它是 indicators.DoubleRingBuffer

(vec (.getDeclaredMethods (class b))) 将给你一个向量,其中包含所有声明在你的类中的方法,就像是Java类一样,这样你就可以看到它们的签名。

现在,按照签名调用你的方法,使用这些方法名称和参数。

我有一种感觉,问题在于Scala处理方法参数默认值的方式。

编辑:正如OP在评论中描述的那样,不是这个问题。

如果这不起作用,你可以尝试将你的Scala字节码反编译为Java,以找出DoubleRingBuffer类的外观。


谢谢!反编译解决了问题 - Java 代码完美无缺,最终发现是增量构建工具出了一些奇怪的 bug - 重新启动后就按预期工作了!顺便说一下,我使用了 http://java.decompiler.free.fr/ 这个很棒的工具。 - josh
1
@josh:你也可以尝试使用scalac -print命令,它会打印出一个“解糖”版本,该版本仍然是Scala语法,但与Java同构,即所有高级Scala功能都被移除。此外,还有scalap命令,类似于javap,即反编译.class文件。 - Jörg W Mittag

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接