chqdrian
chqdrian

Reputation: 345

Changing Return type of a function in Scala

I need to write a function that has the return type NodeSeq (scala.xml.NodeSeq),
In the below function, I'm trying to get the NodeSeq of an XML file, by evaluating an expression using the below code. The compiler throws type mismatch error.

import scala.reflect.runtime.universe

def someFunc(params): NodeSeq = {
  some code
  ....
  val evaluator = universe.runtimeMirror(getClass.getClassLoader).mkToolBox()
  val data: NodeSeq = evaluator.eval(evaluator.parse(expression))  // return type - Any

  if(data.getClass.getName == scala.xml.NodeSeq) data else NodeSeq.Empty
}

the val data should ideally contain NodeSeq (from the data I have), but I'm evaluating an expression, the return type of the expression can be anything,

I understand, why I can't return NodeSeq using the above code,
the best I could come up with is the last if condition.
Is there anything, that I can do to change the return type of this function to NodeSeq from Any?

Upvotes: 1

Views: 367

Answers (1)

Mikhail Ionkin
Mikhail Ionkin

Reputation: 625

You can use pattern matching when the result (or action) depends on the type or value. It is a more powerful version of the switch.

The code below was already submitted by Luis Miguel Mejía Suárez in a comment on a deleted answer:

val data: NodeSeq = evaluator.eval(evaluator.parse(expression)) match {
  case n: NodeSeq => n
  case _ => NodeSeq.Empty
}

In some cases the compiler will warn you if you have not considered all possible cases (match may not be exhaustive). Both Intellij Idea and SBT will warn you, if you use fruitless type in pattern matching (like List[String] instead of List[Int]).

You should not compare String (data.getClass.getName) with Class (scala.xml.NodeSeq), because you will get compile error. It's not recommended use class name to check class (like data.getClass.getName == "scala.xml.NodeSeq"), because at least it is not checked by compiler, and because you will get NullPointerException if data == null.

There is another way: check class by isInstanceOf. But it is also not recommended, because isInstanceOf does not check the type of generics: List(1).isInstanceOf[List[String]] will return true.

Sorry for my English.

Upvotes: 1

Related Questions