ScalaJS中的创建类型安全库是否可以从JavaScript中使用?

时间:2016-09-04 06:12:56

标签: scala scala.js

如果是这样怎么样?在我的上一个问题中,我问为什么这个片段崩溃了:

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

在:

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

而且回应是因为我错过了callMe的隐含论据。之前我没有想到这一点,因为,Scala正在自动神奇地提供它,所以这只是第一次尝试:

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

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

问题是:

如何编写类型安全(至少在编译时,不需要动态检查)使用Scala的普通功能的库,如整数,数组,函数, ScalaJS中的泛型和ClassTag哪些可以轻松地从JavaScript中使用?我真的希望它是可能的。

*:我的意思是没有任何神秘的要求,例如从JavaScript手动构建ClassTag

1 个答案:

答案 0 :(得分:1)

您可能希望在示例中使用js.Array

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

Array是一个Scala / Java样式数组,并且不透明JavaScript(即对其执行任何操作都是未定义的行为)。 js.Array是一个可以从JavaScript实际使用的JavaScript数组。与大多数Scala集合一样,它不需要构造ClassTag