2012-12-03 5 views
0

스칼라에서 클래스 필드에 제약 조건을 두는 방법은 무엇입니까? 패키지에 도메인의 모델이 있고 다른 패키지에 내 모델을 인스턴스화하는 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의 필드에 제약 조건을 적용하려고합니다. 다른 말로하면 나는이 필드에 대한 정보를 정의해야합니다. 맞습니까? 어떻게해야합니까?

나는 것을하려고했으나 제약이 존중되지 않습니다

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 값으로 초기화해야한다는 것입니다. 따라서 "이 필요합니다"라는 메시지는 좋은 해결책이 아닙니다. 감사합니다.

답변

0

추상 발 :

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

만들기 : 당신이 경우 클래스를 사용하여 피할 수 있습니다 상태 개체를 원하기 때문에

new { val name = "init" } with Init 
+0

안녕하세요, 답장을 보내 주셔서 감사합니다. 그러나 당신의 솔루션은 나를 위해 작동하지 않습니다. val이 아니라 "var"이 필요합니다. 컨트롤은 처음 인스턴스를 시작할 때뿐만 아니라 값을 변경할 때마다 수행되어야합니다. 의견이 있으십니까? – user1826663

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에 의해 생성 된 세터가 name_= 방법을 무시하는 당신은 이미 할 수있다 알고있다.