简体   繁体   English

通过在Scala中使用TypeTag实现多态返回类型

[英]Polymorphic return type by using TypeTag in Scala

What I want to do is returning generics type in Scala function by using TypeTag. 我想做的是通过使用TypeTag在Scala函数中返回泛型类型。 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. 因为返回of方法类型在编译类型中不是固定的。 Is there any way to get the type information from TypeTag and embed the type in the returned type? 有什么方法可以从TypeTag获取类型信息并将该类型嵌入返回的类型中吗?

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. 因此,我们需要修复从A的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 . 它需要IntChildStringChildimplicit修饰符。 There's no need to have another type parameter named T , as it would always be the same as A in your example. 不需要另一个名为T类型参数,因为它在您的示例中始终与A相同。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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