2017-02-19 4 views
0

생성자에서 하나의 단일 매개 변수를 수정하려는 경우. 스칼라 경우 클래스에서 간결한 방법으로 스칼라 클래스 생성자에서 하나의 값 수정

방법은 두 번 무시됩니다 적용됩니다. 을 적용하지 않는 한은 보조 생성자에 적용됩니다 (말장난 없음). 하나의 생성자에서 하나 개의 입력을 수정하는 방법

관련?

기준 :

  • 클래스는 불변 데이터를 보유해야합니다. 모든 데이터에 액세스 할 수 있어야합니다.

  • 사례 클래스가 아니어도됩니다.

  • 또한 적용 메서드를 사용할 필요가 없습니다.

  • 여분의 사용되지 않은 매개 변수가 없습니다. 아래 예제에서는 _fistName에 계속 액세스 할 수 있지만 사용하지 않습니다.

경우 클래스 사람 ( 이 lastName : 문자열, _fistName : 문자열, ...) 는 {게으른 발 fistName = _fistName.toLowerCase가}

답변

0

당신이 게시 한 참조가 보인다 대답도 많이있다. 내가

  1. 생각할 수

    두 가지 간단한 방법은 abstract case class 당신이

  2. var 같은 경우 클래스의 멤버를 정의하고 돌연변이를 원하는 값을 돌연변이 것 동반자 객체를 정의합니다.

예 : (scalatest을 사용)

class CaseClassSpecs extends FunSpec { 

    describe("case class modify") { 

    it("APPROACH 1 : modifies abstract case class member") { 

     object Item { 
     def apply(itemId: String, itemName: String) :Item = new Item(itemId.toLowerCase, itemName) {} 
     } 

     abstract case class Item private (val itemId: String, itemName: String) 

     val item1 = Item("SKU-ONE", "Shirts") 

     assert(item1.itemId == "sku-one") 
     assert(item1.itemName == "Shirts") 
    } 

    it("APPROACH 2 : modifies case class member which is var") { 

     case class Item (var itemId: String, itemName: String) { 
     itemId = itemId.toLowerCase() 
     } 

     val item1 = Item("SKU-ONE", "Shirts") 

     assert(item1.itemId == "sku-one") 
     assert(item1.itemName == "Shirts") 
    } 
    } 
    } 
+0

나는 누가 당신의 대답과 내 질문을 downvoted 모르겠다. 그러나 나는 당신의 답을 upvoted. 내가 제공 한 링크 중 아무 것도 나에게 답을주지 못했다. –

2

두 가지 간단한 접근법이 있습니다.

사용 클래스 : 특성 +를 사용

class Person(first: String, last: String) { 
    val firstName = first.toLowerCase 
    val lastName = last.toLowerCase() 
} 

val person = new Person("Adam", "Smith") 
println(person.firstName + " " + person.lastName) // adam smith 

은 (의 적용 객체) :

trait Person { 
    val firstName: String 
    val lastName: String 
} 

object Person { 
    def apply(first: String, last: String) = new Person { 
    override val firstName: String = first.toLowerCase 
    override val lastName: String = last.toLowerCase 
    } 
} 

val person = Person("Adam", "Smith") 
println(person.firstName + " " + person.lastName) // adam smith 

주 클래스가 new 인스턴스화해야합니다 (apply()로 만든) 특성은하지 않지만.

왜 케이스 클래스가 없습니까? 글쎄요, 그들은 ADTs (abstract data types)로서의 역할을하도록 설계되었습니다. 기본적으로, 그들은 어떤 논리없이 어떤 데이터를위한 컨테이너로 생각됩니다. 그렇기 때문에 그들은 apply()을 즉시 사용할 수 있습니다. 이를 재정의하려면 클래스에 사례 클래스의 의미가 없음을 의미합니다.

@prayag가 당신이 그것을 케이스 클래스에 넣도록 돕기 위해 노력했다는 것을 알 수 있습니다. 그러나 심각하지 않으면, 질문에 그렇게 말하면, 그것을 만든다.

+0

나는 수업을 사용하는 방법을 좋아한다. 멋져. 생성자에 전달할 매개 변수가 많은 경우 나머지를 복사하는 대신 하나의 변수 만 변경하는 방법이 있습니까? 나는 케이스 클래스의 conciseness를 좋아한다. –

+0

예, 생성자에서 앞에 val을 추가하기 만하면된다. 사례 클래스는 자동으로 그것을 얻습니다. 예 : 'class Person (첫 번째 : String, val lastName : String) { val firstName = first.toLowerCase } ' – slouc

+0

오케이, 알겠습니다. 그러나 나는 분명히 반복하지 않기를 바란다 : class Person (first : String, last : String, x : Int, y : Int, ...) val lastName = 마지막 val lastName = last, val x = x, val y = y ... 나는 지름길이 없다고 생각한다. –