0

我只是想在下面的示例中检查 T 类型的任何出现。断言失败(试试我)

val seq = List(AcceptableRisk, UnacceptableRisk)
def any[T] = 
    seq.collect { case x: T => x }.nonEmpty 

assert(any[UnknownRisk] == false) 

trait Risk
case class AcceptableRisk() extends Risk 
case class UnacceptableRisk() extends Risk 
case class UnknownRisk() extends Risk

有一个编译警告:

jdoodle.scala:5: warning: abstract type pattern T is unchecked since
it is eliminated by erasure
   seq.collect { case x: T => x }.nonEmpty
                         ^

为什么会失败?

4

2 回答 2

1

由于您的域是有限的,我会选择这样的:

trait Risk extends Product with Serializable
object Risk {
  def isUnacceptableRisk(risk: Risk): Boolean = risk match {
    case UnacceptableRisk(_) => true
    case _                   => false
  }
  // Repeat for other types if needed.
}

final case class AcceptableRisk(name: String) extends Risk 
final case class UnacceptableRisk(name: String) extends Risk 
final case class UnknownRisk(name: String) extends Risk

然后你可以:seq.exists(Risk.isUnacceptableRisk)

可以使用typeclasses完成更通用的解决方案,如下所示:

trait Is[T] {
  type U
  def check(t: T): Boolean
}

object Is {
  type Aux[T, _U] = Is[T] { type U = _U }
}

object syntax {
  object is {
     implicit class SeqOps[T](private val seq: Seq[T]) extends AnyVal {
       def any[U <: T](implicit ev: Is.Aux[T, U]): Boolean =
         seq.exists(ev.check)
     }
  } 
}

trait Risk extends Product with Serializable
object Risk {
  implicit final val IsUnacceptableRisk: Is.Aux[Risk, UnacceptableRisk] =
    new Is[Risk] {
      override type U = UnacceptableRisk
      override def check(risk: Risk): Boolean = risk match {
        case UnacceptableRisk(_) => true
        case _                   => false
      }
    }
    // Repeat for other types if needed.
}

final case class AcceptableRisk(name: String) extends Risk 
final case class UnacceptableRisk(name: String) extends Risk 
final case class UnknownRisk(name: String) extends Risk

import syntax.is._
List(AcceptableRisk("foo"), UnacceptableRisk("bar")).any[UnacceptableRisk] // true.

但真诚的恕我直言,没有真正赢得太多的工作太多了。

于 2020-04-15T03:26:35.530 回答
0

它有助于:

def any[T <: Risk: Manifest] = 
    seq.collect { case x: T => x }.nonEmpty 
于 2020-04-15T00:51:27.303 回答