首页 > 解决方案 > 我可以使用案例对象作为方法参数吗

问题描述

我想在不使用match.

我想做多个方法实现,但它只适用于类,使用案例类会太成问题。

以下方法不起作用:

sealed trait Result

object Result {
  final case object Result1 extends Result
  final case object Result2 extends Result
  final case object Result3 extends Result
}

def doSth(result: Result)=
  consumeResult(result)

private def consumeResult(result: Result.Result1) = ???

private def consumeResult(result: Result.Result2) = ???

private def consumeResult(result: Result.Result3) = ???

标签: scalacasevisitor-pattern

解决方案


直接的解决方法是type像这样使用对象:

private def consumeResult(result: Result.Result1.type) = ???
etc..

然而,更广泛的代码不起作用:

def doSth(result: Result) =
  consumeResult(result)

函数重载发生在编译时,而不是运行时。到您调用consumeResult运行时类型时,它会丢失。编译时类型是Result这样的,它不会匹配任何重载版本的consumeResult.

类型类可能是最好的方法:

trait Consume[T <: Result] {
  def consume()
}

object Consume {
  implicit object consume1 extends Consume[Result.Result1.type] {
    def consume() = {
      println("Consume1")
    }
  }

  implicit object consume2 extends Consume[Result.Result2.type] {
    def consume() = {
      println("Consume2")
    }
  }
}

def doSth[T <: Result](result: T)(implicit ev: Consume[T]) =
  ev.consume()


doSth(Result.Result1) // Prints "Consume1"
doSth(Result.Result2) // Prints "Consume2"
doSth(Result.Result3) // Does not compile, no matching typeclass

推荐阅读