【问题标题】:Is it possilble to a create type-safe library in ScalaJS for using from JavaScript?是否可以在 Scala JS 中创建类型安全的库以供 JavaScript 使用?
【发布时间】:2016-09-04 19:58:01
【问题描述】:

如果有怎么办?在我的最后一个问题中,我问为什么这个 sn-p 会崩溃:

@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 中的泛型和 ClassTags 可以很容易地*从 JavaScript 中使用?我真的希望这是可能的。

*:我的意思是没有像从 JavaScript 手动构造 ClassTags 这样的神秘要求。

【问题讨论】:

    标签: scala scala.js


    【解决方案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

    【讨论】:

    • 我是ScalaJS的新手,所以我真的不知道什么是自动兼容的,什么需要区别对待。谢谢,您的解决方案效果很好。
    • 什么是直接兼容的,什么不是直接兼容的,记录在scala-js.org/doc/interoperability/types.html
    猜你喜欢
    • 1970-01-01
    • 2011-11-03
    • 2018-11-28
    • 2021-10-14
    • 1970-01-01
    • 2021-10-26
    • 1970-01-01
    • 1970-01-01
    • 2011-10-11
    相关资源
    最近更新 更多