2013-11-14 54 views
0

如何找出某個對象是否爲值類類型,以便在下面的示例中,測試會打印出該id是否爲AnyVal?Scala TypeTags或Manifest:是否可以確定某個類型是否是Value類?

class MyId(val underlying: Int) extends AnyVal 

class AnyValSuite extends FunSuite { 

    class Sample { 
    def doIt[T](t: T)(implicit tag: TypeTag[T]): Unit = { 
     if(???) println(s"$t is an AnyVal")  
    } 
    } 

    test("Getting info if a type is a value class") { 
    new Sample().doIt(new MyId(1)) 
    } 
} 

@senia:謝謝你的回答。完美的作品。是否有可能找出Value類正在包裝的原始類型?

擴展現在例如:

class MyId(val underlying: Int) extends AnyVal 
class NonAnyValId(val underlying: Int) 

class AnyValSuite extends FunSuite { 

    class Sample { 
    def doIt[T](t: T)(implicit tag: TypeTag[T]): Unit = { 
     if(implicitly[TypeTag[T]].tpe <:< typeOf[AnyVal]) println(s"$t is an AnyVal") 
     else println(s"$t is not an AnyVal") 
    } 
    } 

    test("Getting info if a type is a value class") { 
    new Sample().doIt(new MyId(1)) 
    new Sample().doIt(new NonAnyValId(1)) 
    new Sample().doIt(1) 
    } 
} 

回報:

[email protected] is an AnyVal 
[email protected] is not an AnyVal 
1 is an AnyVal 

編輯2: 現在用包裹類型檢查:

import org.scalatest.FunSuite 
import scala.reflect.runtime.universe._ 

class MyId(val underlying: Int) extends AnyVal 
class NonAnyValId(val underlying: Int) 

class AnyValSuite extends FunSuite { 

    class Sample { 
    def doIt[T](t: T)(implicit tag: TypeTag[T]): Unit = { 
     val tpe= implicitly[TypeTag[T]].tpe 
     if(tpe <:< typeOf[AnyVal]) { 
     println(s"$t is an AnyVal") 
     val fields = tpe.members.filter(! _.isMethod) 

     fields.size match { 
      case 0 => println("has no fields, so it's a primitive like Int") 
      case 1 => { 
      println("has a sole field, so it's a value class") 
      val soleValueClassField = fields.head.typeSignature 
      println("of type: " + soleValueClassField) 
      if(typeOf[Int] == soleValueClassField) println("It wraps a primitive Int") 
      } 
      case 2 => throw new Exception("should never get here") 
     } 
     } 
     else println(s"$t is not an AnyVal") 
    } 
    } 

    test("Getting info if a type is a value class") { 
    new Sample().doIt(new MyId(1)) 
    println 
    new Sample().doIt(new NonAnyValId(1)) 
    println 
    new Sample().doIt(1) 
    } 
} 

回報:

[email protected] is an AnyVal 
has a sole field, so it's a value class 
of type: Int 
It wraps a primitive Int 

[email protected] is not an AnyVal 

1 is an AnyVal 
has no fields, so it's a primitive like Int 

只是不知道是否有一些簡單的解決方案?

回答

5

你可以只檢查是否TAnyVal亞型。

import scala.reflect.runtime.universe.{TypeTag, typeOf} 

def doIt[T: TypeTag](t: T): Unit = { 
    if(implicitly[TypeTag[T]].tpe <:< typeOf[AnyVal]) println(s"$t is an AnyVal")  
} 

doIt(new MyId(1)) 
// [email protected] is an AnyVal 
+0

@flavian:你是什麼意思?您可以請添加代碼示例。 – senia

+0

@senia感謝您的完美!是否有可能獲得值類的包裝原始類型? – longliveenduro

+0

@longliveenduro:'value class'應該只有一個字段,所以你可以使用scala反射來找到這個字段。 – senia

相關問題