根据Scala中类型证据的存在进行分支的惯用方法

根据Scala中类型证据的存在进行分支的惯用方法,scala,types,implicits,Scala,Types,Implicits,我发现自己不止一次地在写以下丑陋的模式: class Something[A, B](implicit ev: A =:= B = null) { ... def doStuff { if (ev == null) ... // know that A is not the same as B else ... // safely assume A is equal to B } } 更糟糕的是,当ev!=null,我有时会写一些异端邪说,比

我发现自己不止一次地在写以下丑陋的模式:

class Something[A, B](implicit ev: A =:= B = null) {
  ...

  def doStuff {
    if (ev == null) ... // know that A is not the same as B
    else ...            // safely assume A is equal to B
  }
}
更糟糕的是,当
ev!=null
,我有时会写一些异端邪说,比如
someB.asInstanceOf[A]

只需使用类型类

trait DoStuff[A, B] {
  def apply(): Unit
}

trait DoStuff0 {
  implicit def neDoStuff[A, B]: DoStuff[A, B] =
    new DoStuff[A, B] { def apply(): Unit = ... body of your ev == null case ...
}

object DoStuff extends DoStuff0 {
  implicit def eqDoStuff[A]: DoStuff[A, A] =
    new DoStuff[A, A] { def apply(): Unit = ... body of your ev != null case ...
}

class Something[A, B](implicit ds: DoStuff[A, B]) {
  ...
  def doStuff: Unit = ds()
}
只需使用类型类

trait DoStuff[A, B] {
  def apply(): Unit
}

trait DoStuff0 {
  implicit def neDoStuff[A, B]: DoStuff[A, B] =
    new DoStuff[A, B] { def apply(): Unit = ... body of your ev == null case ...
}

object DoStuff extends DoStuff0 {
  implicit def eqDoStuff[A]: DoStuff[A, A] =
    new DoStuff[A, A] { def apply(): Unit = ... body of your ev != null case ...
}

class Something[A, B](implicit ds: DoStuff[A, B]) {
  ...
  def doStuff: Unit = ds()
}

为什么不像对待其他任何地方出现的
null
(即
Option(ev)
)的可能性那样对待它?为什么不像对待其他任何地方出现的
null
(即
Option(ev)
)的可能性那样对待它?如果该代码>更改为>@Cloudtech,这取决于上下文,但如果,在这里,当
某个东西被实例化时,实例可以被一次性修复,那么为什么要推迟它,并可能在每次调用该方法时支付调用它的费用呢?如果该代码>更改为>@Cloudtech,这取决于上下文,但是,如这里所示,当
某个东西
被实例化时,可以一次性修复该实例,那么为什么要推迟该实例,并可能在每次调用该方法时支付调用该实例的费用呢?