The below code is taken from Spark SQL. It performs extraction, but the castType
is a companion object - one would call it as TypeCast.castTo("abc", StringType)
.
Could somebody please explain how pattern matching works with companion objects under the hood?
private[csv] def castTo(datum: String, castType: DataType): Any = {
castType match {
case _: ByteType => datum.toByte
case _: ShortType => datum.toShort
case _: IntegerType => datum.toInt
case _: LongType => datum.toLong
case _: FloatType => datum.toFloat
case _: DoubleType => datum.toDouble
case _: BooleanType => datum.toBoolean
case _: DecimalType => new BigDecimal(datum.replaceAll(",", ""))
case _: TimestampType => Timestamp.valueOf(datum)
case _: DateType => Date.valueOf(datum)
case _: StringType => datum
case _ => throw new RuntimeException(s"Unsupported type: ${castType.typeName}")
}
}
ADDED: Based on my understanding extractin/pattern matching is usually implemented by the unapply method of the companion object. This is an example of how case classes are implemented under the hood
trait User {
def name: String
}
class FreeUser(val name: String) extends User
class PremiumUser(val name: String) extends User
object FreeUser {
def unapply(user: FreeUser): Option[String] = Some(user.name)
}
object PremiumUser {
def unapply(user: PremiumUser): Option[String] = Some(user.name)
}
I don't really understand how the same thing can be done for companion classes
I have never worked with Spark, so I cannot answer with specific Spark knowledge.
But the pattern matching in your example seems to be ordinary type based pattern matching.
castType
is an instance of the typeDataType
that has several subclasses e.g.ByteType
. The pattern matching just tests whether thecastType
object belongs to the specific class (e.g.ByteType
).Because there are just singleton instances of the several sub-types, the matching does not need to provide the matches instance at all. That is why the match uses just a placeholder
_
.