Scala asInstanceOf with parameterized types

前端 未结 5 1215
清歌不尽
清歌不尽 2020-12-02 14:17

I would like to write a function that casts to type A, where A can be e.g. List[Int], or a more complicated parameterized type like Map[Int, List[Int]].

def          


        
5条回答
  •  渐次进展
    2020-12-02 14:54

    Consider this solution:

    trait -->[A, B] {
      def ->(a: A): B
    }
    
    implicit val StringToInt = new -->[String, Int] {
      def ->(a: String): Int = a.toInt
    }
    
    implicit val DateToLong = new -->[java.util.Date, Long] {
      def ->(a: java.util.Date): Long = a.getTime
    }
    
    def cast[A,B](t:A)(implicit ev: A --> B):B= ev.->(t)
    

    The advantage is that:

    1. It is type safe - the compiler will tell you if the type cannot be casted
    2. You can define casting rules by providing proper implicits

    Now you can use it so:

    scala>  cast(new java.util.Date())
    res9: Long = 1361195427192
    
    scala>  cast("123")
    res10: Int = 123
    

    EDIT

    I've spent some time and wrote this advanced code. First let me show how to use it:

    scala>    "2012-01-24".as[java.util.Date]
    res8: java.util.Date = Tue Jan 24 00:00:00 CET 2012
    
    scala>    "2012".as[Int]
    res9: Int = 2012
    
    scala>    "2012.123".as[Double]
    res12: Double = 2012.123
    
    scala>    "2012".as[Object]   // this is not working, becouse I did not provide caster to Object
    :17: error: could not find implicit value for parameter $greater: -->[String,Object]
    "2012".as[Object]
    ^
    

    Pretty nice? See the scala magic:

    trait -->[A, B] {
      def ->(a: A): B
    }
    
    implicit val StringToInt = new -->[String, Int] {
      def ->(a: String): Int = a.toInt
    }
    
    implicit val StringToDate = new -->[String, java.util.Date] {
      def ->(a: String): java.util.Date = (new java.text.SimpleDateFormat("yyyy-MM-dd")).parse(a)
    }
    
    implicit val StringToDouble = new -->[String, Double] {
      def ->(a: String): Double = a.toDouble
    }
    
    trait AsOps[A] {
      def as[B](implicit > : A --> B): B
    }
    
    implicit def asOps[A](a: A) = new AsOps[A] {
      def as[B](implicit > : A --> B) = > ->(a)
    }
    

提交回复
热议问题