向Scala Maps添加隐式getAs()方法

时间:2016-08-29 14:25:05

标签: scala implicit

所以我想添加一个隐式方法,它通过检查键的类型来返回键的值。

import scala.reflect.ClassTag

object MyMap {
  implicit class FlexMap[A](map: Map[String, A]) {
    def getAs[B](key: String)(implicit ct: ClassTag[B]): Option[B] = map.get(key) match {
      case Some(value: ct.runtimeClass) => Some(value.asInstanceOf[B])
      case _ => None
    }
  }
}

但是当我尝试编译它时,我得到:

  

类型runtimeClass不是scala.reflect.ClassTag [B]

的成员

即使我使用了,我也会得到同样的错误:

case Some(value) if (value.isInstanceOf[ct.runtimeClass])

我不知道如何解决这个问题。有什么想法吗?

2 个答案:

答案 0 :(得分:1)

ClassTag有一个unapply方法可以为您执行实际的投射,并返回一个选项。

implicit class FlexMap[A](map: Map[String, A]){                                                        
  def getAs[B](key: String)(implicit ct: ClassTag[B]): Option[B] = 
    map.get(key).flatMap(ct.unapply)     
}                                                                                                      

答案 1 :(得分:0)

在Scala中,类型不是值,它们属于不同的类别,因此无法从方法返回类型。 .runtimeClass实际上返回了Class类型的值,该值不能用于预期类型的​​位置。您可能需要的是:

object MyMap {
  implicit class FlexMap[A](map: Map[String, A]) {
    def getAs[B](key: String)(implicit ct: ClassTag[B]): Option[B] = map.get(key) match {
      case Some(value: B) => Some(value)
      case _ => None
    }
  }
}

另一种说同样的方式:

def getAs[B](key: String)(implicit ct: ClassTag[B]): Option[B] = 
  map.get(key) flatMap {
    case value: B => Some(value)
    case _        => None
  }