使用不透明类型(Char 和 Long)

Working with opaque types (Char and Long)

我正在尝试导出算法的 Scala 实现以用于 JavaScript。我正在使用 @JSExport。该算法适用于 Scala CharLong 值,这些值在 interoperability guide.

中标记为 opaque

我想知道 (a) 这是什么意思;以及 (b) 处理此问题的建议是什么。

我想这意味着我应该避免 CharLong 并使用 String 加上对长度的运行时检查(或者可能使用无形 Sized集合)和 Int 代替。

但欢迎提出其他想法。

更多详情...

我正在查看的代码类型是:

@JSExport("Foo")
class Foo(val x: Int) {
  @JSExport("add")
  def add(n: Int): Int = x+n
}

...按预期工作:new Foo(1).add(2) 产生 3.

将类型替换为 Long 相同的调用报告: java.lang.ClassCastException: 1 is not an instance of scala.scalajs.runtime.RuntimeLong(以及与采用 and return Char 的方法类似的东西)。

不透明意味着

  • 没有对应的JavaScript类型
  • 无法从 JavaScript 创建 那个类型的值(除非有 @JSExported 构造函数)
  • 无法操纵该类型的值(除了调用@JSExported方法和字段)

仍然可以从 Scala.js 代码接收该类型的值,传递它,然后返回给 Scala.js 代码。也总是可以调用 .toString(),因为 java.lang.Object.toString()@JSExported。除了 toString()CharLong 都没有导出任何东西,所以你不能用它们做任何其他事情。

因此,如您所见,JavaScript 1 不能用作 Scala.js Long,因为它的类型不正确。 'a' 也不是有效的 Char(但它是有效的 String)。

因此,正如您自己推断的那样,您确实必须避免使用不透明类型,如果您需要从 JavaScript create/manipulate 它们,请使用其他类型。 Scala.js端可以使用语言中的标准工具来回转换,例如someChar.toIntsomeInt.toChar

选择哪种类型最好取决于您的应用。对于 Char,它可能是 IntString。对于 Long,它可能是 String、一对 Int,甚至可能是 Double,如果可能的值从不使用超过 52 位的精度。