■ はじめに
今更だが、Scala の asInstanceOf / isInstanceOf を扱う。
目次
【1】asInstanceOf 1)使用上の注意 【2】isInstanceOf 【3】サンプル 例1:implicit Class の メソッド
【1】asInstanceOf
* Scala の キャスト
1)使用上の注意
* 例えば、「"false".asInstanceOf[Boolean]」とすると例外がでる
例:文字列 to 真偽 / 文字列 to 数字 での例外
object Hello { def main(args: Array[String]): Unit = { val target1 = "false" // ! Error ! // java.lang.ClassCastException: class java.lang.String cannot be cast to class java.lang.Boolean // (java.lang.String and java.lang.Boolean are in module java.base of loader 'bootstrap') //val result1 = target1.asInstanceOf[Boolean] //println(result1) val target2 = "1" // ! Error ! // java.lang.ClassCastException: class java.lang.String cannot be cast to class java.lang.Integer // (java.lang.String and java.lang.Integer are in module java.base of loader 'bootstrap') //val result2 = target2.asInstanceOf[Int] //println(result2) // } }
【2】isInstanceOf
* Scala の データ型判定
【3】サンプル
例1:implicit Class の メソッド
* 以下の関連記事のサンプルを拡張したものを作ってみた
https://dk521123.hatenablog.com/entry/2024/07/24/120726
import ConfigType._ import scala.language.implicitConversions import scala.util.{Failure, Success, Try} sealed trait ConfigType object ConfigType { final case class ConfigString(str: String) extends ConfigType final case class ConfigInt(int: Int) extends ConfigType final case class ConfigBoolean(bool: Boolean) extends ConfigType final case class ConfigStrings(list: List[String]) extends ConfigType def toConfigType[T](value: T): ConfigType = { value match { case intValue: Int => ConfigInt(intValue) case boolValue: Boolean => ConfigBoolean(boolValue) case stringValue: String => ConfigString(stringValue) case listValues: List[String] => ConfigStrings(listValues) case _ => throw new IllegalArgumentException("No supported") } } implicit class ConfigTypeEx(val self: ConfigType) { final def getValue[T]: T = { val value = self match { case ConfigString(str) => str case ConfigInt(int) => int case ConfigBoolean(bool) => bool case ConfigStrings(list) => list case _ => throw new IllegalArgumentException("Not Supported") } // ★asInstanceOf★ value.asInstanceOf[T] } } implicit class OptionConfigTypeEx(val self: Option[ConfigType]) { def getValueOrElse[T](default: T): T = { // ★isInstanceOf★ if (self.isDefined && self.get.isInstanceOf[ConfigType]) Try(self.get.getValue[T]) match { case Failure(_) => default case Success(value) => value } else default } } } object Hello { def main(args: Array[String]): Unit = { val mapper: Map[String, Option[ConfigType]] = Map( "key1" -> Some(toConfigType("Hello")), "key2" -> Some(toConfigType(2)), "key3" -> Some(toConfigType(true)), "key4" -> Some(toConfigType(List("value4_1", "value4_2", "value4_3"))), "key5" -> None ) mapper.foreach { case (key: String, value: Option[ConfigType]) => if (value.isEmpty) { println(s"${key} - ${value.getValueOrElse[String]("NoneDefault")}") println(s"${key} - ${value.getValueOrElse[Int](123)}") println(s"${key} - ${value.getValueOrElse[Boolean](true)}") println(s"${key} - ${value.getValueOrElse[List[String]](List("NoneA", "NoneB"))}") } else { // ここで match 使ったら、意味ないけど、、、 value.get match { // String -> key1 = value1 case ConfigString(str) => println(s"${key} - ${value.getValueOrElse[String]("default")}") // Int -> key2 = 2 case ConfigInt(int) => println(s"${key} - ${value.getValueOrElse[Int](193)}") // Boolean -> key3 = true case ConfigBoolean(bool) => println(s"${key} - ${value.getValueOrElse[Boolean](true)}") // List[String] -> key4 = value4_1,value4_2,value4_3 case ConfigStrings(list) => println(s"${key} - ${value.getValueOrElse[List[String]](List("C", "D"))}") } } println("******************") } } }
出力結果例
key4 - List(value4_1, value4_2, value4_3) ****************** key5 - NoneDefault key5 - 123 key5 - true key5 - List(NoneA, NoneB) ****************** key1 - Hello ****************** key2 - 2 ****************** key3 - true ******************
参考文献
https://xuwei-k.hatenablog.com/entry/20101103/1288766564
https://qiita.com/Apacher-inf/items/a680334f8d49f361ae74
関連記事
Scala ~ 環境構築編 ~
https://dk521123.hatenablog.com/entry/2023/03/10/193805
Scala ~ 入門編 ~
https://dk521123.hatenablog.com/entry/2023/03/12/184331
Scala ~ 基本編 / Option型 ~
https://dk521123.hatenablog.com/entry/2023/03/09/000000
Scala ~ 基本編 / ジェネリック
https://dk521123.hatenablog.com/entry/2023/03/21/003817
Scala ~ 基本編 / コレクション ~
https://dk521123.hatenablog.com/entry/2023/03/13/000345
Scala ~ コレクションで使えるメソッド ~
https://dk521123.hatenablog.com/entry/2023/09/07/223422
Scala ~ 基本編 / メソッド ~
https://dk521123.hatenablog.com/entry/2023/03/03/000000
Scala ~ 可変長引数 ~
https://dk521123.hatenablog.com/entry/2024/07/30/155036
Scala ~ 基本編 / 繰り返し ~
https://dk521123.hatenablog.com/entry/2023/01/24/000000
Scala ~ 基本編 / トレイト ~
https://dk521123.hatenablog.com/entry/2023/09/10/204016
Scala ~ 基本編 / パターンマッチング ~
https://dk521123.hatenablog.com/entry/2023/06/06/233614
Scala ~ 基本編 / 例外処理 ~
https://dk521123.hatenablog.com/entry/2023/10/05/000135
Scala ~ Enum ~
https://dk521123.hatenablog.com/entry/2023/01/05/000000
Scala ~ 代数的データ型 / ADT ~
https://dk521123.hatenablog.com/entry/2024/07/23/193246