Scala.js和ClassTag导致崩溃

时间:2016-09-03 17:36:57

标签: scala scala.js

我在Scala中有以下代码,它工作正常:

object TestVanilla {
  def callMe[A: ClassTag](f: Int => A): Array[A] = Array(f(4))
}

val res = TestVanilla.callMe(_ + "x");
println(res.mkString(", "));

结果:

4x

完整代码:http://scalafiddle.net/console/20337e889ee17ca9862a8317918ae5d9

我把它重写为ScalaJS,但似乎崩溃了标签:

@JSExport("Test") object TestScalaJs {
  @JSExport def callMe[A: ClassTag](f: js.Function1[Int, A]): Array[A] = Array(f(4))
}

来自JS的电话:

var res = Test().callMe(function(x) {return x + 'x';});
console.log('TestScalaJs:', res.join(', ')); 

崩溃:

$c_jl_Throwable.fillInStackTrace__jl_Throwable  @   VM153:4161
$c_sjsr_UndefinedBehaviorError.fillInStackTrace__jl_Throwable   @   VM153:9241
$c_jl_Throwable.init___T__jl_Throwable  @   VM153:4177
$c_sjsr_UndefinedBehaviorError.init___T__jl_Throwable   @   VM153:9248
$c_sjsr_UndefinedBehaviorError.init___jl_Throwable  @   VM153:9244
$throwClassCastException    @   VM153:196
$as_s_reflect_ClassTag  @   VM153:7824
$c_LTestScalaJs$.callMe @   VM153:2061
(anonymous function)    @   VM155:2
$s_Lscalatags_jsdom_Frag$class__applyTo__Lscalatags_jsdom_Frag__Lorg_scalajs_dom_raw_Element__V @   VM153:1108
$c_Lscalatags_JsDom$TypedTag.applyTo__O__V  @   VM153:9981
$c_Lfiddle_Fiddle$.println__sc_Seq__V   @   VM153:2113
$c_LScalaFiddle$.init___    @   VM153:2021
$m_LScalaFiddle$    @   VM153:2034
(anonymous function)    @   VM154:1
(anonymous function)    @   VM77 resultframe?theme=light:32

完整代码:https://beetta.scalafiddle.io/sf/YzdMmU/1

Scala.js不支持ClassTag s?或者我做错了什么?

EDIT2:创建了follow up question。这个问题得到了解答,即使它实际上并没有为我解决任何问题 - 我的不好,我问得很差。

请不要在这里回答EDIT1,而是在后续问题中回答。

EDIT1:我没有说清楚。代码是我希望在ScalaJS中编写的小型库的简化问题,该库旨在从JavaScript中使用。我正在寻找一种方法来解决这个相当简单的问题 - 创建类型安全的数组,同时允许JS实际上能够轻松调用该方法。也许可以使用一些代理/外观?

1 个答案:

答案 0 :(得分:3)

Scala.js确实支持ClassTag。您的问题是,您希望JavaScript能够填写Scala隐式参数,而这是无法做到的。您的方法定义

@JSExport def callMe[A: ClassTag](f: js.Function1[Int, A]): Array[A] = Array(f(4))
与往常一样,在Scala中,

等同于

@JSExport def callMe[A](f: js.Function1[Int, A])(implicit ct: ClassTag[A]): Array[A] = Array(f(4))

清楚地突出显示callMe 2 参数。 Scala类型检查器可以自动填充第二个(隐式)参数,但JavaScript不能这样做。从JavaScript中,你必须显式地传递第二个参数。