Scala:泛型方法隐式参数

Scala:泛型方法隐式参数,scala,generics,implicit,Scala,Generics,Implicit,我碰到了一个代码片段,无法理解它。该片段是: implicit val dummyVisit = Visit("", 1L, 1, 1, 1, 1L) implicit val dummyOrder = Order("", 1L, 1, 1, 1, 1L) def process[T](events : Array[T])(implicit t: T):Unit = { println(t) if(!events.isEmpty) t match {

我碰到了一个代码片段,无法理解它。该片段是:

  implicit val dummyVisit = Visit("", 1L, 1, 1, 1, 1L)
  implicit val dummyOrder = Order("", 1L, 1, 1, 1, 1L)

  def process[T](events : Array[T])(implicit t: T):Unit = {
    println(t)
    if(!events.isEmpty)
      t match {
        case r: Order => processOrder(events.asInstanceOf[Array[Order]])
        case r: Visit => processVisit(events.asInstanceOf[Array[Visit]]);
      }
  }

  def processOrder(arr: Array[Order]): Unit = { println(arr.size) }
  def processVisit(arr: Array[Visit]): Unit = { println(arr.size) }
隐式
变量
t
,要求
dummyVisit
dummyOrder
存在

问题

  • 这是使用隐式参数的正确方法吗

  • 有没有更好的方法可以在不使用隐式参数的情况下获取
    T
    的类类型


  • 捕获参数类型是隐式参数的预期用途之一

    虽然我会写一些不同的东西:

    import scala.reflect.ClassTag
    
    // `sealed` ensures that no extra evidences can be defined elsewhere
    sealed abstract class Evidence[T](implicit val tag: ClassTag[T])
    object Evidence {
      implicit object visitEvidence extends Evidence[Visit]
      implicit object orderEvidence extends Evidence[Order]
    }
    
    def process[T](events: Array[T])(implicit ev: Evidence[T]) = {
      import ev.tag // import ClassTag[T] to allow matching on array element types
      events match {
        case Array() => // don't process empty arrays
        case arr: Array[Order] => processOrder(arr)
        case arr: Array[Visit] => processVisit(arr)
      }
    }
    
    此代码避免创建无意义的伪实例,并使用
    asInstanceOf
    进行类型转换

    进一步的一步是在隐式参数中捕获处理操作本身,并完全避免每种情况下的显式
    匹配。这也称为类型类模式:


    使用隐式解析规则搜索隐式我不明白你的问题?您可以对访问或订单数组调用process(xs)。如果相应的隐式不在作用域中,则process(xs)不会像使用多态性或缺少多态性那样编译look
    sealed trait ProcessArray[T] {
      def apply(arr: Array[T]): Unit
    }
    object ProcessArray {
      implicit object processVisitArray extends ProcessArray[Visit] {
        def apply(arr: Array[Visit]) = { println(arr.size) }
      }
      implicit object processOrderArray extends ProcessArray[Order] {
        def apply(arr: Array[Order]) = { println(arr.size) }
      }
    }
    def process[T](array: Array[T])(implicit proc: ProcessArray[T]) = {
      if (array.nonEmpty) proc(array)
    }