非变量类型参数

Pie*_*rre 2 scala

我有以下型号:

case class Questionnaire(List(Question[_])
case class Question[A](text: String, Answer[A])
case class Answer[A](value: A)
Run Code Online (Sandbox Code Playgroud)

我试图根据问卷类型设置问卷的所有答案(答案可以是String,Double或LocalDate类型):

val questionnaire = getMockQuestionnaireWithoutAnswers()
questionnaire.questions.map {
  case x: Question[String] => //...default the answer.value to some random string
  case x: Question[Double] => //...default the answer.value to some random double
  case x: Question[LocalDate] => //...default the answer.value to some random date
}
Run Code Online (Sandbox Code Playgroud)

但是我收到了错误:

非变量类型参数类型为pattern examplespacespace.Question [String]的字符串未选中,因为它已被擦除消除.

我不想将所有类型包装成这样的类:

case class StringQuestion(question: Question[String])
Run Code Online (Sandbox Code Playgroud)

避免此错误的最佳方法是什么?

maa*_*asg 6

类型擦除消除了匹配表达式提供的参数类型,这意味着之间的差Question[String],并Question[Int]得到在运行时丢失.

避免这种情况的一种方法是提供该类型的具体实现,以便JVM无法"擦除"它.

我过去曾经使用过这种结构.可能还有其他方法,但这个方法很简单:

case class Answer[A](a:A)
case class Question[A](text: String, answer: Answer[A])
case class Questionnaire(questions: List[Question[_]])

// concrete types
trait StringQuestion extends Question[String]
trait DoubleQuestion extends Question[Double]
trait IntQuestion extends Question[Int]

def resolve(questions: List[Question[_]]): List[String] = {
  questions.map {
    case x: StringQuestion => "Stringy"
    case x: DoubleQuestion => "Doubly"
    case x: IntQuestion => "Inty"
  }
}
Run Code Online (Sandbox Code Playgroud)


Nya*_*vro 5

试试这个方法:

questionnaire.questions.map {
  case Question(text, Answer(d:Double)) => //
  case Question(text, Answer(s:String)) => //
  case Question(text, Answer(ld:LocalDate)) => //
}
Run Code Online (Sandbox Code Playgroud)

您可以访问问题的文本(文本)和答案的值(d、s 或 ld)

您还可以为变量使用别名:

questionnaire.questions.map {
  case q @ Question(text, a @ Answer(d:Double)) => //
  case q @ Question(text, a @ Answer(s:String)) => //
  case q @ Question(text, a @ Answer(ld:LocalDate)) => //
}
Run Code Online (Sandbox Code Playgroud)