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

Ric*_*way 6 scala.js

我正在尝试导出用于JavaScript的算法的Scala实现.我正在使用@JSExport.该算法适用于Scala Char和在互操作性指南Long中标记为不透明的值.

我想知道(a)这意味着什么; (b)处理此事的建议是什么.

我认为这意味着我应该避免CharLong使用String加上运行时检查长度(或者可能使用无形的Sized集合)而Int不是.

但欢迎其他想法.

更多详情...

我正在看的代码类型是:

@JSExport("Foo")
class Foo(val x: Int) {
  @JSExport("add")
  def add(n: Int): Int = x+n
}
Run Code Online (Sandbox Code Playgroud)

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

Long相同的调用报告替换类型:( java.lang.ClassCastException: 1 is not an instance of scala.scalajs.runtime.RuntimeLong和使用和返回的方法类似Char).

sjr*_*jrd 9

不透明意味着

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

仍然可以从Scala.js代码接收该类型的值,传递它,并将其返回给Scala.js代码.它也总是可以打电话.toString(),因为java.lang.Object.toString()@JSExported.此外toString(),既不输出Char也不Long输出任何东西,所以你不能用它们做任何其他事情.

因此,正如您所经历的那样,JavaScript 1不能用作Scala.js Long,因为它不是正确的类型.两者都不是'a'有效的Char(但它是有效的String).

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

选择哪种类型最好取决于您的应用.因为Char,它可能是IntString.因为Long,它可能是String一对Ints,或者甚至Double可能的值从不使用超过52位的精度.