方法重载中的类型擦除问题

问题描述

我有两个具有以下签名的重载方法-

def fun(x: Seq[String]): Future[Seq[Int]] = ???
def fun(x: Seq[(String,String)]): Future[Seq[Int]] = ???

由于类型擦除,这些方法不能重载,因此显示编译错误。我尝试使用类型标签作为解决方法-

def fun[t: TypeTag](values: Seq[T]): Future[Seq[Int]] = {
    typeOf[T] match {
        case t if t =:= typeOf[String] => ???
        case t if t =:= typeOf[(String,String)] => ???
        case _ => ???    // Should not come here
     }
}

此方法面临两个问题-

  1. 如何使用Seq中的值?
  2. 如何避免发生Should not come here案件?

谢谢。

解决方法

尝试使用DummyImplicit而非TypeTag方法

def fun(x: Seq[String]): Future[Seq[Int]] = ???
def fun(x: Seq[(String,String)])(implicit ev: DummyImplicit): Future[Seq[Int]] = ???

如何使用Seq中的值?

请注意,即使TypeTag启用了克服类型擦除功能,我也不认为编译器会自动插入强制类型转换,因此您应该手动调用asInstanceOf或同等功能

case t if t =:= typeOf[String] => 
  val vs: Seq[String] = values.asInstanceOf[Seq[String]]
  ???

请注意,TypeTag需要依赖scala-reflect.jar(例如,如果我们关心包装的大小,这可能是不利的)。

,

在这种情况下,常见的做法是使用Magnet Pattern

,

对于方法重载,您可以使用

  1. DummyImplicit(请参阅 @MarioGalic 的答案)

    def fun(x: Seq[String]): Future[Seq[Int]] = ???
    def fun(x: Seq[(String,String)])(implicit ev: DummyImplicit): Future[Seq[Int]] = ???
    
    fun(Seq("a","b"))
    fun(Seq(("a","b"),("c","d")))
    
  2. type class

    trait FunTypeclass[A] {
      def fun(x: A): Future[Seq[Int]]
    }
    object FunTypeclass {
      implicit val string: FunTypeclass[Seq[String]] = x => ???
      implicit val stringTuple2: FunTypeclass[Seq[(String,String)]] = x => ???
    }
    def fun[A](x: A)(implicit ftc: FunTypeclass[A]): Future[Seq[Int]] = ftc.fun(x)
    
    fun(Seq("a","d")))
    

  1. magnet

    import scala.language.implicitConversions
    
    trait FunMagnet {
      def fun(): Future[Seq[Int]]
    }
    object FunMagnet {
      implicit def fromString(x: Seq[String]): FunMagnet = () => ???
      implicit def fromStringTuple2(x: Seq[(String,String)]): FunMagnet = () => ???
    }
    def fun(x: FunMagnet): Future[Seq[Int]] = x.fun()
    
    fun(Seq("a","d")))
    

Overloading methods based on generics

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...