Writing a generic cast function Scala

前端 未结 3 1135
萌比男神i
萌比男神i 2020-12-09 10:11

I am trying to achieve to write a method that casts a value of Any to a specific type and returns option instead of throwing an exception like instanceOf. Scala does not beh

3条回答
  •  心在旅途
    2020-12-09 10:49

    Erasure rains on your parade here. Therefore at runtime the type A is not known anymore and asInstanceOf[A] is compiled to a no-op. It just makes the compiler believe that the resulting value is of type A, but that is not actually ensured at runtime.

    You can use Scala's manifests to work around it, though. Unfortunately the JVM's handling of primitive types / boxing forces us to do some extra work.

    The following works, although it doesn't handle "weak conformance" of types, meaning that e.g. an Int is not considered a Long, so cast[Long](42) returns None.

    def cast[A : Manifest](value: Any): Option[A] = {
      val erasure = manifest[A] match {
        case Manifest.Byte => classOf[java.lang.Byte]
        case Manifest.Short => classOf[java.lang.Short]
        case Manifest.Char => classOf[java.lang.Character]
        case Manifest.Long => classOf[java.lang.Long]
        case Manifest.Float => classOf[java.lang.Float]
        case Manifest.Double => classOf[java.lang.Double]
        case Manifest.Boolean => classOf[java.lang.Boolean]
        case Manifest.Int => classOf[java.lang.Integer]
        case m => m.erasure
      }
      if(erasure.isInstance(value)) Some(value.asInstanceOf[A]) else None
    }
    

提交回复
热议问题