寻找使 Java 库可供 Scala.js 的 JavaScript 和 JVM 端访问的方法 cross-built项目,请考虑以下实验:
想象一下 Scala.js 项目需要高级矩阵数学功能,例如 Singular Value Decomposition 。尽管JavaScript世界有Numeric.js JVM 世界有很多选择,JAMA其中最重要的是,在提出此问题时不存在跨构建 Scala.js 解决方案。
我们有什么选择?
- 为 Scala.js 重新编写或移植矩阵库。
- 将 Numeric.js 外观和 JAMA 封装到通用 Scala.js 接口(interface)中。
- 为 Numeric.js 编写外观,然后使用 Nashorn 进行编译用于 JVM 支持。
- 使用 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 会为您做到这一点,就像它对 Double
和 number
所做的那样。
统一 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/