简体   繁体   中英

Polymorphic return type by using TypeTag in Scala

What I want to do is returning generics type in Scala function by using TypeTag. Here is the example code.

trait Parent[T]

object IntChild extends Parent[Int]
object StringChild extends Parent[String]

object SomeClass {
  def of[A: TypeTag]: Parent[T] = {
    getElementType[A] match {
      case Int => IntChild
      case String => StringChild
    }
  }
}

SomeClass.of[Array[Int]]

But it throws a compile error. Because the returned type of of method is not fixed in the compile type. Is there any way to get the type information from TypeTag and embed the type in the returned type?

What I am expecting is like

// T is inferred from TypeTag A.
def of[A: TypeTag, T]: Parent[T] = {
  //...
}

I found this code also has not passed compile. So we need to fix the type information inferred from A's TypeTag.

def of[A: TypeTag]: Parent[_] = {
  //...
}

This is the error.

type mismatch;
[error]  found   : Array[Int]
[error]  required: Array[_$1]

How can I get the element type in advance?

I'm not sure it's possible with those definitions. How about changing the definitions a little?

trait Parent[T]

implicit object IntChild extends Parent[Int]
implicit object StringChild extends Parent[String]

object SomeClass {
  def of[A: Parent]: Parent[A] = implicitly
}

This makes sure everything is done at the type level so that you get the return type you want. It requires the implicit modifier on IntChild and StringChild . There's no need to have another type parameter named T , as it would always be the same as A in your example.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM