scalabeginner

Type Conversions and Safe Casting

Convert between types safely: numeric conversions, asInstanceOf alternatives, and pattern-based casting.

scala
import scala.util.Try

@main def run(): Unit =
  // Numeric conversions
  val i: Int = 42
  val l: Long = i.toLong
  val d: Double = i.toDouble
  val f: Float = i.toFloat
  val s: Short = i.toShort
  val b: Byte = i.toByte
  println(s"Int $i -> Long $l, Double $d, Float $f")

  // Widening (safe, automatic)
  val autoLong: Long = 42    // Int -> Long automatic
  val autoDouble: Double = 42 // Int -> Double automatic
  println(s"Auto widening: $autoLong, $autoDouble")

  // String conversions
  val str = "42"
  val parsed = str.toInt
  val safeParsed = str.toIntOption
  val tryParsed = Try(str.toInt).toOption
  println(s"\nParsed: $parsed")
  println(s"Safe: $safeParsed")
  println(s"Try: $tryParsed")

  // Safe parsing
  println(s"Bad parse: ${"abc".toIntOption}")       // None
  println(s"Double: ${"3.14".toDoubleOption}")       // Some(3.14)
  println(s"Boolean: ${"true".toBooleanOption}")     // Some(true)
  println(s"Long: ${"9999999999".toLongOption}")     // Some(...)

  // Safe casting with pattern matching
  def safeCast[T](value: Any): Option[T] =
    value match
      case t: T @unchecked => Some(t)
      case _ => None

  // Better: match on specific types
  def describe(value: Any): String = value match
    case i: Int    => s"Int: $i"
    case s: String => s"String: '$s' (len=${s.length})"
    case d: Double => s"Double: $d"
    case l: List[?] => s"List of ${l.size} items"
    case m: Map[?, ?] => s"Map of ${m.size} entries"
    case null => "null"
    case other => s"Unknown: ${other.getClass.getSimpleName}"

  println(s"\n${describe(42)}")
  println(describe("hello"))
  println(describe(3.14))
  println(describe(List(1, 2, 3)))
  println(describe(Map("a" -> 1)))

  // isInstanceOf checks
  val x: Any = "hello"
  if x.isInstanceOf[String] then
    val s2 = x.asInstanceOf[String]
    println(s"\nCast: $s2")

  // Prefer pattern matching over isInstanceOf
  x match
    case s2: String => println(s"Pattern: $s2")
    case _ => ()

  // Numeric formatting
  val pi = 3.14159
  println(f"\nFormatted: $pi%.2f")
  println(s"As int: ${pi.toInt}")
  println(s"Rounded: ${math.round(pi)}")
  println(s"Ceil: ${math.ceil(pi).toInt}")
  println(s"Floor: ${math.floor(pi).toInt}")

  // BigDecimal for precision
  val price = BigDecimal("19.99")
  val tax = BigDecimal("0.08")
  val total = price * (1 + tax)
  println(f"\nTotal: $$${total.setScale(2, BigDecimal.RoundingMode.HALF_UP)}")

  // Char conversions
  val ch = 'A'
  println(s"\nChar '$ch' -> Int ${ch.toInt}, code: ${ch.toLower}")
  println(s"Int 65 -> Char '${65.toChar}'")
  println(s"Digit '7' -> Int ${Character.getNumericValue('7')}")

Use Cases

  • Safe data type conversions
  • Parsing string inputs
  • Numeric precision handling

Tags

Related Snippets

Similar patterns you can reuse in the same workflow.