Working with opaque types (Char and Long)

守給你的承諾、 提交于 2020-01-02 04:11:14

问题


I'm trying to export a Scala implementation of an algorithm for use in JavaScript. I'm using @JSExport. The algorithm works with Scala Char and Long values which are marked as opaque in the interoperability guide.

I'd like to know (a) what this means; and (b) what the recommendation is for dealing with this.

I presume it means I should avoid Char and Long and work with String plus a run-time check on length (or perhaps use a shapeless Sized collection) and Int instead.

But other ideas welcome.

More detail...

The kind of code I'm looking at is:

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

...which works just as expected: new Foo(1).add(2) produces 3.

Replacing the types with Long the same call reports: java.lang.ClassCastException: 1 is not an instance of scala.scalajs.runtime.RuntimeLong (and something similar with methods that take and return Char).


回答1:


Being opaque means that

  • There is no corresponding JavaScript type
  • There is no way to create a value of that type from JavaScript (except if there is an @JSExported constructor)
  • There is no way of manipulating a value of that type (other than calling @JSExported methods and fields)

It is still possible to receive a value of that type from Scala.js code, pass it around, and give it back to Scala.js code. It is also always possible to call .toString(), because java.lang.Object.toString() is @JSExported. Besides toString(), neither Char nor Long export anything, so you can't do anything else with them.

Hence, as you have experienced, a JavaScript 1 cannot be used as a Scala.js Long, because it's not of the right type. Neither is 'a' a valid Char (but it's a valid String).

Therefore, as you have inferred yourself, you must indeed avoid opaque types, and use other types instead if you need to create/manipulate them from JavaScript. The Scala.js side can convert back and forth using the standard tools in the language, such as someChar.toInt and someInt.toChar.

The choice of which type is best depends on your application. For Char, it could be Int or String. For Long, it could be String, a pair of Ints, or possibly even Double if the possible values never use more than 52 bits of precision.



来源:https://stackoverflow.com/questions/27821841/working-with-opaque-types-char-and-long

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!