簡體   English   中英

如何在Scala中正確使用asInstanceOf

[英]how to use asInstanceOf properly in Scala

我一直在玩基本的Scala數據類型。 我注意到scala.Any類定義方法asInstanceOf[T0]: T0這里 API有它可以“將接收器對象轉換為T0類型”。 使用此方法作為起點,我想調查Scala中的強制轉換。 另外,我查看了stackoverflow以獲取有關此主題的其他問題,我想出了這個有了這些信息,我寫了一個愚蠢的程序。

         package com.att.scala
         import com.att.scala.Sheltie

         object Casting {

             //def foo(x: String){ 
             def foo(x: Int) {
              println("x is " + x)
             //if(x.isInstanceOf[String])
              if(x.isInstanceOf[Int])
                 println("Int x is " + x)
                //println("String x is " + x)
             }

            def entry() {
               //val double: Any = 123.123
               val double: Double = 123.23
               val int = double.asInstanceOf[Int] //exception expected here
               //val str: String = "123"
               foo(int) 
             }

         }

我的目標是了解在以下情況下會發生什么(以及為什么):1)從Any類型轉換為Int。 2)從Double類型轉換為Int 3)從String轉換為Int

  1. 在第一種情況下,當我運行程序為 - com.att.scala.Casting.entry時,我得到了一個運行時ClasscastException,如下所示。 例外如下所示:

    java.lang.ClassCastException: java.lang.Double cannot be cast to java.lang.Integer at scala.runtime.BoxesRunTime.unboxToInt(Unknown Source) at com.att.scala.Casting$.entry(Casting.scala:17)

  2. 在第二種情況下,我得到以下結果:int是123 x是123 Int x是123

在這種情況下,代碼應該產生ClasscastException,但它不會。 這是我的擔心。

  1. 在第三種情況下,我得到了classcastexception:

java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer at scala.runtime.BoxesRunTime.unboxToInt(Unknown Source) at com.att.scala.Casting$.entry(Casting.scala:20)

在這個例子中,我的目標是了解Scala中的基礎知識。 我知道這個例子無論如何都不是一個現實世界的例子,但我試圖讓我的頭腦纏繞在基礎上。

Java(和Scala)允許您將原始doubleint (在Scala的情況下, DoubleInt )。 另一方面,您無法將java.lang.Doublejava.lang.Int

當你將Double聲明為Any ,你明確要求編譯器忘記你給它一個Double 因此,為了支持Any接口,編譯器將值存儲為boxed double(即java.lang.Double )。

這種行為確實令人困惑,但這不是一個錯誤。 根據Scala語言規范 §12.1:

如果T是數值類型(第12.2節),則特別處理測試x.asInstanceOf [T]。 在這種情況下,強制轉換將轉換為轉換方法x.toT(第12.2.1節)的應用程序。

我認為你混淆了“演員”和“轉換”這兩個詞。

標准的轉換方法開始to ,例如20d.toInt將轉換值20Double類型的值20 Int

另一方面, asInstanceOf是一種特殊類型的鑄造方法。 它只是通知編譯器該值是其參數中指定的類型,如果在運行時期間調用此方法的值與您在type參數中指定的值不匹配,則會拋出異常。 a.asInstanceOf[B]所提供的價值a必須是一個類型的B或繼承它-否則,你會得到一個例外。

剛做了更多的測試(編譯和運行),我想這可能是來自asInstanceOf的一個bug,它不會進行強制轉換。

最后一行命令給我編譯錯誤:

警告:(46,38)無結果類型測試:Int類型的值也不能是S println(listTemp2(1).isInstanceOf [S])//將無法編譯

                                 ^ 

val listOfS = Some(List(S("i1", "k1", "s1"), S("i2", "k2", "s2")))
val listTemp:Seq[K] = listOfS.get.asInstanceOf[Seq[K]]
val listTemp2:Seq[Int] = listOfS.get.asInstanceOf[Seq[Int]]
println("ListTemp:")
println(listTemp(1)) //print S(i2,k2,s2)
println(listTemp(1).isInstanceOf[S])   // true
println(listTemp(1).isInstanceOf[K])   // false
println(listTemp2(1)) //print S(i2,k2,s2)
println(listTemp2(1).isInstanceOf[Int])   // false
println(listTemp2(1).isInstanceOf[S]) // won't compile

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM