0

在 Scala 中,如何对类的字段进行约束?在一个包中,我有模型的域,在另一个包中,我有 dsl 来实例化我的模型。该模型的基本形式是这样的:

abstract class Element {
  var name: String
  var description: String
  var types : Set[Type]  
}

class SAComponent (var name :String,
        var description : String,
        var properties : Set[Property] = Set(),
        var types : Set[Type] = Set(),
        ) extends Component

元素是我模型的根。我想对 Element 的字段施加约束,以便每个继承名称和描述以及 Element 类型的类都尊重这些约束。换句话说,我需要为这些字段定义我得到的。正确的?我应该怎么做?

我试过了,但没有遵守约束:

abstract class Element {    
  def name: String
  def name_= (value: String): Unit = {if (isBadValue(value)throw new IllegalArgumentException
  name = value
  }
  var description : String,
  var types : Set[Type] = Set }

  class Component (override var name : String, var description: String) extends Element

问题是某些必须遵守约束的字段,在具体类的构造函数中必须初始化为空值。所以“要求”对我来说不是一个好的解决方案。谢谢你们。

4

2 回答 2

1

在初始化时检查对您不起作用,因为您需要有状态的对象,这可以通过使用案例类来避免。copy(field=value)您可能希望使用为案例类自动生成的来创建新对象,而不是改变对象的状态。

如果您仍然想使用有状态的对象,我想您想要类似的东西

abstract class Element {    
  private var _name: String = null
  def name_= (value: String) {
    require(!isBadValue(value),"Bad Value")
    _name = value
  }
  def name = _name
  def isBadValue(value: String): Boolean
}
class Component (initialName : String) extends Element {
  name = initialName
  def isBadValue(value: String) = value=="name"
}
val c = new Component(null)  // works
c.name = "name"              // exception

需要指出的另一件事:override var name代码中生成的 setter 会覆盖您name_=可能已经知道的方法。

于 2012-12-04T15:58:32.720 回答
0

抽象值:

trait Init {
  val name: String
  require(!isBadName(name))
  def isBadName(name: String) = true
}

创建:

new { val name = "init" } with Init
于 2012-12-03T18:46:58.243 回答