2016-09-15 2 views
1

스칼라 ClassTags 작업 AnyVal 객체와 함께 사용할 때 classTag.runtimeClass.isInstance가 제대로 작동하지 않습니다. 다음은 테스트 할 수있는 스 니펫입니다. AnyVal 오브젝트에 대해이 작업을 수행하기위한 아이디어가 있습니까?AnyVal에 대해 ClassTag.runtimeClass.isInstance가 작동하지 않습니다.

val c = classTag[Double].runtimeClass 
println(c) // double 
println(c == classOf[Double]) // true 
println(c.isInstance(0.0)) // false 

isInstanceObject을 취

import scala.reflect.ClassTag 
import scala.reflect.runtime.{universe => ru} 
object Test { 
    def extractField[U: ru.TypeTag](json: Map[String, Any], field: String)(implicit classTag: ClassTag[U]): Option[U] = { 
    json.get(field) match { 
     case Some(value) => 
     if(classTag.runtimeClass.isInstance(value)) 
      Some(value.asInstanceOf[U]) 
     else { 
      None 
     } 
     case _ => 
     None 
    } 
    } 
    val map: Map[String,Any] = Map("k1" -> 2.0, "k2" -> "v") 
    extractField[Double](map,"k1") // RETURNS NONE 
    extractField[String](map,"k2") // RETURNS Some("v") 
} 

은 BTW 나는 여기에 같은 문제를 보여주는 훨씬 간단 코드는 스칼라 2.10

+0

이것은 스칼라 버그입니까? – Mikel

+0

isInstance 대신 isInstanceOf를 사용하십시오. http://stackoverflow.com/questions/26168721/difference-between-isinstance-and-isinstanceof – Samar

+0

일반 유형이기 때문에 value.isInstanceOf [U]를 사용할 수 없으므로 classtag 사용 (value.isInstanceOf [U]는 지우기로 인해 제거되므로 선택 취소됩니다.) – Mikel

답변

2

와 함께 일하고 있습니다. classOf[Double]은 JVM 프리미티브 double (및 classTag[Double].runtimeClass은 동일 함)의 "클래스"를 나타냅니다. 객체는 프리미티브가 될 수 없으므로 classOf[Double].isInstance(something)은 항상 false입니다.

Map[String, Any]에는 실제로는 AnyVal이 포함되지 않지만 개체 만 포함됩니다. 당신이

val map: Map[String,Any] = Map("k1" -> 2.0, "k2" -> "v") 

2.0

을 작성할 때 자동으로 코드가 올바르게를 알 수 있도록이 키 아래에는 Double 없다 java.lang.Double에 박스입니다. 하지만 당신은 (내가 어딘가에 표준 라이브러리라고 생각하지만, 위치를 기억하지 않는) 간단한 도우미 함수를 작성할 수 있습니다 다음

private val boxedClasses = 
    Map[Class[_], Class[_]](classOf[Double] -> classOf[java.lang.Double], ...) // the rest of AnyVal classes 
def boxed(c: Class[_]) = boxedClasses.getOrElse(c, c) 

case Some(value)에 : 물론

if(boxed(classTag.runtimeClass).isInstance(value)) 
    Some(value.asInstanceOf[U]) 

이 수 이 차이는 컴파일 타임을 제외하고는 존재하지 않으므로 맵에 Doublejava.lang.Double의 차이점을 알 수 없습니다.

+0

AnyVal 개체에 대해이 검사를 구현하는 방법이 있습니까? – Mikel

+0

솔루션을 추가했습니다. –

+0

감사합니다. 이 까다로운 해결책이이 작업을 수행하는 유일한 방법이라는 사실에 놀랐습니다 ... – Mikel

관련 문제