与我的特征相同类型的列表,但仅限于实现

时间:2018-04-25 16:27:54

标签: scala list traits

让我们说我有一个简单的特征叫做约束:

trait Constraint {

  def description: String

  def constraintValue: Int

  def applyConstraint
}

...以及两个扩展此特征的类:

class ConstraintA(val constraintValue: Int) extends Constraint {

  override def description: String = "CONSTRAINT_A"

  override def applyConstraint: Unit = {
    // ...
  }
}

class ConstraintB(val constraintValue: Int) extends Constraint {

  override def description: String = "CONSTRAINT_B"

  override def applyConstraint: Unit = {
    // ...
  }
}

我正在读取XML文件并实例化ConstraintA和Constraint B列表(具体实现)。

这是我用来读取文件并创建列表的代码:

val xml = XML.loadFile(xmlFilePath)

val readConstraints = (xml \ "constraints") (0).attributes.map {
   c =>
     c.key match {
       case "CONSTRAINT_A" => new ConstraintA(c.value.text.toInt)
       case "CONSTRAINT_B" => new ConstraintB(c.value.text.toInt)
       case _ => Nil
     }
 }

问题是我想返回List[Constraint]但是我收到错误消息:类型List [Object]的表达式不符合预期类型List [Constraint]

有关语言为何不推断类型的任何提示?

谢谢!

2 个答案:

答案 0 :(得分:1)

实际上问题是如果您希望编译器推断您的操作类型,则需要返回相同的两种不同类型。

showButton

在最后一种情况下,你将返回Nil,它是什么都没有。

在CONSTRAINT_A的情况下,您将返回CONSTRAINT_A,就像CONSTRAINT_B一样。这就是编译器将其视为对象列表的原因。

答案 1 :(得分:1)

match表达式可以返回ConstraintNil,唯一的常见子类型是Any,因此生成的类型为Any。因此map操作返回List[Any]

修复方法是从匹配表达式中删除case _

Constraint标记为sealed以避免来自编译器的投诉