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
).
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
@JSExport
ed constructor) - There is no way of manipulating a value of that type (other than calling
@JSExport
ed 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 @JSExport
ed. 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 Int
s, 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