Scala.js 和 ClassTag 导致崩溃
Scala.js and ClassTag results in crash
我在 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
吗?还是我做错了什么?
EDIT2:创建了 。这个问题得到了回答,尽管它实际上并没有为我解决任何问题 - 我的错,我问得很糟糕。
请不要在这里回答 EDIT1,而是在后续问题中回答。
EDIT1:我没有说清楚。该代码是我想用 ScalaJS 编写的小型库的简化问题,该库旨在从 JavaScript 开始使用。我正在寻找一种方法来解决这个看似微不足道的问题——创建类型安全的数组,同时允许 JS 实际上能够轻松地调用该方法。也许可以使用一些proxy/facade?
Scala.js 确实支持 ClassTag
s。您的问题是您期望 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 开始,您必须 显式 传递第二个参数。
我在 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
吗?还是我做错了什么?
EDIT2:创建了
请不要在这里回答 EDIT1,而是在后续问题中回答。
EDIT1:我没有说清楚。该代码是我想用 ScalaJS 编写的小型库的简化问题,该库旨在从 JavaScript 开始使用。我正在寻找一种方法来解决这个看似微不足道的问题——创建类型安全的数组,同时允许 JS 实际上能够轻松地调用该方法。也许可以使用一些proxy/facade?
Scala.js 确实支持 ClassTag
s。您的问题是您期望 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 开始,您必须 显式 传递第二个参数。