我有以下型号:
case class Questionnaire(List(Question[_])
case class Question[A](text: String, Answer[A])
case class Answer[A](value: A)
我正在尝试根据问卷类型设置问卷的所有答案(答案可以是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
}
但是我收到了错误:
非变量类型参数类型为pattern examplespacespace.Question [String]的字符串未选中,因为它已被擦除消除。
我不想将所有类型包装成这样的类:
case class StringQuestion(question: Question[String])
避免此错误的最佳方法是什么?
答案 0 :(得分:5)
类型擦除消除了匹配表达式中提供的参数类型,这意味着Question[String]
和Question[Int]
之间的差异在运行时会丢失。
规避这种情况的一种方法是提供该类型的具体实现,使JVM无法“擦除”#34;它
我过去曾使用过这种结构。可能还有其他方法,但这个很简单:
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"
}
}
答案 1 :(得分:3)
尝试这种方法:
questionnaire.questions.map {
case Question(text, Answer(d:Double)) => //
case Question(text, Answer(s:String)) => //
case Question(text, Answer(ld:LocalDate)) => //
}
您可以访问问题(文本)的文本和答案(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)) => //
}