scala - JSweet 能否有效地移植 Java 库以在交叉构建的 Scala.js 项目中使用?

标签 scala scala.js scalajs-bundler jsweet

寻找使 Java 库可供 Scala.js 的 JavaScript 和 JVM 端访问的方法 cross-built项目,请考虑以下实验:

想象一下 Scala.js 项目需要高级矩阵数学功能,例如 Singular Value Decomposition 。尽管JavaScript世界有Numeric.js JVM 世界有很多选择,JAMA其中最重要的是,在提出此问题时不存在跨构建 Scala.js 解决方案。

我们有什么选择?

  1. 为 Scala.js 重新编写或移植矩阵库。
  2. 将 Numeric.js 外观和 JAMA 封装到通用 Scala.js 接口(interface)中。
  3. 为 Numeric.js 编写外观,然后使用 Nashorn 进行编译用于 JVM 支持。
  4. 使用 JSweet 将 JAMA 转换为 JavaScript以及时尚合适的 Scala.js 外观。

此问题反射(reflect)了选项 4。

修复后JAMA for the JSweet transpiler ,将转译后的 JavaScript 发布为 CommonJS module through npm ,并写作Scala.js facades对于 CommonJS 模块,Scala 代码现在可以在 JVM 端访问 Jama,并在 JS 端访问它的端口。

不幸的是,JVM端的核心数据结构在Scala语法中的类型是:double[][]、Array[Array[Double]],但是JSweet将其转换为JavaScript数组类型,js.Array[js.Array Scala.js 语法中的 [Double]]。

现在,从 Scala.js 交叉构建的角度来看,存在两个名称相同、功能相同、但完全不同且独立的库。

根据 Scala 语法,我们可以在 JS 端构造 3D 单位矩阵,如下所示:

new Matrix(
  js.Array[js.Array[Double]](
    new js.Array[Double](1.0, 0.0, 0.0),
    new js.Array[Double](0.0, 1.0, 0.0),
    new js.Array[Double](0.0, 0.0, 1.0)
   )
 )

在 JVM 方面,我们这样写:

new Matrix(
  Array[Array[Double]](
    new Array[Double](1.0, 0.0, 0.0),
    new Array[Double](0.0, 1.0, 0.0),
    new Array[Double](0.0, 0.0, 1.0)
  )
)

我们如何统一这两种实现?

是否有一个技巧可以将 js.Array 和 Array 等同起来?

您是否会建议一种完全不同的方法来使 Java 库可供交叉构建的 Scala.js 项目访问?

最佳答案

让我从一个简单的问题开始:

Is there a trick to equate js.Array and Array?

不,不存在这样的“技巧”。这些数据结构根本不同。 js.Array 的长度是可变的,并且可以使用其他属性进行修补。 Array是Java的定长数组。如果有任何方法可以将它们等同起来,Scala.js 会为您做到这一点,就像它对 Doublenumber 所做的那样。

统一 API 的一种相对简单的方法是在 Scala.js 代码中重建 JAMA 的 API,其中每个类都是来自 JSweet 编译库的外观 JS 类的包装器。这使得 JAMA 的 Scala 级 API 在 Scala/JVM 和 Scala.js 之间完全等效。它确实需要编写一些代码来复制 API,但至少不需要重写方法主体。

一种完全不同的方法,非常激进并且需要大量的工时,即 fork JSweet 编译器来生成 Scala.js IR (.sjsir) 文件而不是 .js 文件。这样,您就可以将 JSweet 生成的 JAMA .sjsir 文件与 Scala.js 生成的应用程序 .sjsir 文件链接在一起。这将提供最大的性能,因为 Scala.js 优化器将能够跨应用程序/库边界进行优化。

关于scala - JSweet 能否有效地移植 Java 库以在交叉构建的 Scala.js 项目中使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51033981/

相关文章:

scala - 如何在 Slick 中参数化表名

Scala - 使用 Bounds 理解类定义

reactjs - 使用 scalajs Diode 和带有为 Posts (序列)定义的处理程序的 ApplicationCircuit,我可以以某种方式将其映射到 ModelProxy[Post] 个体吗?

java - Sbt RootProject 或 ProjectRef 不下载 github 项目内容

scala - 在 spark-streaming 上下文中将 RDD 写入 HDFS

jquery - 如何在 scala.js 中调用 $.modal.close()

scala.js - 如何在 Scala.js 中将 Future 转换为 js.Promise?

scala.js - 在Play中,如何将js文件从ScalaJS客户端复制到服务器?

performance - 如何分解scala.js JS输出的大小