非变量类型参数

时间:2016-10-25 10:03:33

标签: scala

我有以下型号:

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])

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

2 个答案:

答案 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)) => //
}