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 の名前と説明、および型を継承する各クラスがこれらの制約を尊重するようにします。言い換えれば、これらのフィールドの I get を定義する必要があります。右?どうすればいいですか?

私はそれを試しましたが、制約は尊重されません:

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

問題は、具体的なクラスのコンストラクターで、制約を尊重する必要がある一部のフィールドを null 値に初期化する必要があることです。したがって、私にとって「require」は良い解決策ではありません。皆さん、ありがとうございました。

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

指摘すべきもう 1 つのこと: コード内で によって生成されたセッターは、既に知っているメソッドをoverride var nameオーバーライドします。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 に答える