2015-12-29 55 views
0

考慮:使用類型標籤,以檢查的預期類型相匹配實際

sealed trait Parent 
case class Boy(info: String) extends Parent 
case class Girl(info: String) extends Parent 

於是,我寫了下面f功能。給定一個result和期望的結果類型,它打印出的支票是否成功:

import scala.reflect.runtime.universe._ 

scala> def f[A:TypeTag, B:TypeTag](result: A): Unit = typeOf[A] match { 
    | case t if t =:= typeOf[B] => println("good") 
    | case _     => println("bad") 
    | } 
f: [A, B](result: A)(implicit evidence$1: reflect.runtime.universe.TypeTag[A], implicit evidence$2: reflect.runtime.universe.TypeTag[B])Unit 

然後,我跑了它:

scala> f[Boy, Girl](Boy("foo")) 
bad 

scala> f[Boy, Boy](Boy("foo")) 
good 

對於我的測試目的(無視println語句的使用以表示成功),我的使用是否正確?另外,在f中是否存在運行時異常的風險?如果是這樣,怎麼樣?

回答

4

是我使用TypeTag的正確嗎?

TypeTag如果您手動提供類型參數,則不是真的需要。這大致相當於:

def f[A](result: A): Unit = ??? 

f[Girl](boy)甚至不會編譯如果boyBoy,所以失敗的情況下是沒有用的。

對於def f[A: TypeTag, B: TypeTag](result: A): Unit,不需要的result的實際情況,因爲你手動比較TypeTag S的AB,您手動指定類型的參數。這相當於在沒有實例的情況下說typeOf[A] =:= typeOf[B]

另外,在f中是否存在運行時異常的風險?

不是。你不得不做一些真正邪惡的,喜歡做自己TypeTag S:

scala> implicit val tt: TypeTag[Boy] = null.asInstanceOf[TypeTag[Boy]] 
tt: reflect.runtime.universe.TypeTag[Boy] = null 

scala> f[Boy, Girl](Boy("foo")) 
java.lang.NullPointerException 

只要你使用編譯器生成的TypeTag,應該沒事。

+0

'不需要結果的實際情況,因爲你手動comparing'在這種情況下的話,我想簡單地調用'type'方法?例子:'case class F(x:Int)| val y = F(5)| TYPEOF [y.type]'? –

+0

如果你想要一個實例的類型,你需要一個'TypeTag',但問題是你需要兩個類型參數:一個是你想推斷的,另一個是你提供的,但是Scala沒有辦法提供一個並推斷另一個。 –

+0

@ m-z其實,有一種方法可以實現這個結果。 (另外,我會澄清,你的第一句話適用於這個特定的情況,而不是一般情況。) –

0

這裏是你如何提供一個參數,並推斷出其他:

case class F[B: TypeTag] { 
    def apply[A: TypeTag](x: A) = println(typeOf[A] =:= typeOf[B]) 
} 

F[Girl].apply(Boy("Foo")) // Boy inferred for A 
相關問題