5

I was playing around with Scala's structural types when I discovered what looks like a bug to me. Here is my code:

type toD = { def toDouble: Double }
def foo(t: toD) = t.toDouble
foo(5)

And I got this error:

java.lang.NoSuchMethodException
at scala.runtime.BoxesRunTime.toDouble(Unknown Source)
at .foo(<console>:9)
at .<init>(<console>:11)
at .<clinit>(<console>)
at .<init>(<console>:11)
at .<clinit>(<console>)
at $print(<console>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at scala.tools.nsc.interpreter.IMain$ReadEvalPrint.call(IMain.scala:704)
at scala.tools.nsc.interpreter.IMain$Request$$anonfun$14.apply(IMain.scala:920)
at scala.tools.nsc.interpreter.Line$$anonfun$1.apply$mcV$sp(Line.scala:43)
at scala.tools.nsc.io.package$$anon$2.run(package.scala:25)
at java.lang.Thread.run(Unknown Source)

First, I don't know why this isn't working. Second, it's weird that the code compiles just fine and throws an exception at runtime saying that the method doesn't actually exist.

Does anyone have an explanation for this?

4

1 に答える 1

6

これで少し遊んだだけで、本当にバグのようです。ただし、戻り値の型を Any に設定するだけで機能します。

type toD = { def toDouble: Any }

自動ボクシングとプリミティブの処理方法に関係があるのではないかと思います。

編集:

回避策を見つけました:

type toD[A] = { def toDouble: A }
def foo[A](x: toD[A])(implicit y: A =:= Double) = x.toDouble

これにより、toDouble (A) の戻り値が Double であることが保証されます。

于 2012-04-06T11:17:53.133 に答える