2016-03-18 24 views
0

:Scala asIstanceOf neden göz ardı ediliyor? Bu çalışılıyor

şeyler türü Herhangi taşımaktadır Yani rağmen
z = something class = java.lang.String 
y = something class = java.lang.String 

, bu (malzeme atanan) o z biliyor String geçerli: çalıştırmak

object Box { 
    val stuff:Any = "something" 
    def foo[T]():T = { 
    val z = stuff 
    println(s"z = $z class = ${z.getClass.getName}") 
    val y = z.asInstanceOf[T] 
    println(s"y = $y class = ${y.getClass.getName}") 
    y 
    } 
} 

println(Box.foo[Boolean]()) 

Ben çıkışı olsun. Bunu açıkça printol ifademden Boolean olan T'ye göndermeye çalışıyorum. Bu neden havaya uçmuyor? Neden bir String olduğunu düşünüyor?

ben kabloyla Eğer T'nin foo içinde() Ben beklenen başarısızlık çıktı almak Boolean: Bu tamamen benim .asInstanceOf [T] görmezden gibi

z = something class = java.lang.String 
Exception in thread "main" java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Boolean 
    at scala.runtime.BoxesRunTime.unboxToBoolean(BoxesRunTime.java:85) 
    ... 

öyle. Niye ya?

+0

Teşekkür alacak ben kodunuzu modifiye ClassTag

kullanarak silinen türlerini kurtarmak için derleyici anlatmak mümkündür tip silme, '.asInstanceOf [T]' un bir şey yapması imkansızdır. Jenerik türlere yapılan yayınlar da Java'da çalışmaz. Bu JVM'nin bir sınırlaması. Derleyici bu satırda size bir uyarı vermiyor mu? –

+0

'2.12.0-M3' üzerinde, : 18: hata: tür uyumsuzluğu; found: y.type (altta bulunan Boolean ile) gerekli: T y ^ 'y y = z.asInstanceOf [T] '' T '' 'Boolean' ile değiştirilirken. –

cevap

1

Chris Martin'in belirttiği gibi, bu tip silme nedeniyle gerçekleşir. Ancak Scala o bunu çalıştırırsanız örnek olarak biraz, bir ClassCastException kısmi için

object Box { 
    val stuff: Any = "something" 
    def foo[T](implicit ev: ClassTag[T]): T = { 
    val z = stuff 
    println(s"z = $z class = ${z.getClass.getName}") 
    val y = ev.runtimeClass.cast(z) 
    println(s"y = $y class = ${y.getClass.getName}") 
    z.asInstanceOf[T] 
    } 
} 
println(Box.foo[Boolean]) 
İlgili konular