ScalaJS:多态对象的Facade

时间:2015-10-07 18:56:08

标签: scala.js

我想从ScalaJS调用一个类似于以下内容的JS函数:

function parseExpression(s){
  if(isNumber(s)) return {lit:s}
  else{
    return {
      left : leftOp(s)
      oper : operand(s)
      right: rightOp(s)
    }
  }
}

返回的对象可以是两种不同的形状,{lit}{left, oper, right}

我在ScalaJS中定义了以下特征:

@js.native
trait NumLiteral extends js.Object{
  val lit:String = js.native
}

@js.native
trait NumOper extends js.Object{
  val left : NumLiteral | NumOper = js.native
  val oper : String = js.native
  val right: NumLiteral | NumOper = js.native
}

然后我可以将函数parseExpression声明为Function1[String, NumLiteral | NumOper]

检查parseExpression(someExpressionString)的返回值是NumLiteral还是NumOper类型的最佳方式是什么?我可以自由地更改JS和/或Scala代码以实现最优雅的解决方案。

1 个答案:

答案 0 :(得分:0)

我通过在ScalaJS中定义以下内容来解决它:

trait NumExpr

@JSExport
class NumLiteral(val lit:String) extends NumExpr

@JSExport
class NumOper(val left:NumExpr, val oper:String, val right:NumExpr) extends NumExpr

然后将我的JS函数重新定义为:

function parseExpression(s){
  return isNumber(s) ?
    new NumLiteral(s) :
    new NumOper(leftOp(s), operand(s), rightOp(s))
}

这让我可以在parseExpression(someExpressionString)

上进行模式匹配

当然,这会改变原来的JS功能,因此也会改变原来的问题,但它解决了我的问题。