[SCALA] 어떻게 경우 클래스의 인스턴스를 복제하고 스칼라에 하나의 필드를 변경하려면?
SCALA어떻게 경우 클래스의 인스턴스를 복제하고 스칼라에 하나의 필드를 변경하려면?
하자 내가 페르소나, 다른 소셜 네트워크에 사람을 나타내는 경우 클래스가 말한다. 이 클래스의 인스턴스는 완전히 불변이며, 결국 Akka 배우에 의해 수정 될, 불변의 컬렉션에서 개최된다.
지금, 나는 많은 필드가있는 경우 클래스가, 그리고 내가 필드 중 하나,이 같은 업데이트해야합니다라는 메시지가 나타납니다 :
case class Persona(serviceName : String,
serviceId : String,
sentMessages : Set[String])
// Somewhere deep in an actor
val newPersona = Persona(existingPersona.serviceName,
existingPersona.serviceId,
existingPersona.sentMessages + newMessage)
공지 사항 나는 모든 필드, 비록 단 하나의 변화를 지정해야합니다. 복제 existingPersona에 대한 방법과 대체 단 하나 개의 필드가 변경되지 않는 모든 필드를 지정하지 않고 있습니까? 나는 특성으로 그 쓰기 내 모든 경우의 클래스를 사용할 수 있습니까?
페르소나였다 경우지도 같은 경우, 쉽게 할 수있을 것이다.
해결법
-
==============================
1.이러한 사용에 정확히 전용 복사 방법의 경우 classcomes :
이러한 사용에 정확히 전용 복사 방법의 경우 classcomes :
val newPersona = existingPersona.copy(sentMessages = existingPersona.sentMessages + newMessage)
-
==============================
2.2.8 이후, 스칼라의 경우 클래스의 마법을 위해 이름 / 기본 PARAMS을 활용 복사 방법이있다 :
2.8 이후, 스칼라의 경우 클래스의 마법을 위해 이름 / 기본 PARAMS을 활용 복사 방법이있다 :
val newPersona = existingPersona.copy(sentMessages = existing.sentMessages + newMessage)
또한 단순화 사용에 페르소나의 방법을 만들 수 있습니다 :
case class Persona( svcName : String, svcId : String, sentMsgs : Set[String] ) { def plusMsg(msg: String) = this.copy(sentMsgs = this.sentMsgs + msg) }
그때
val newPersona = existingPersona plusMsg newMsg
-
==============================
3.
existingPersona.copy(sentMessages = existingPersona.sentMessages + newMessage)
-
==============================
4.볼품없는 라이브러리에 렌즈를 사용하는 것이 좋습니다 :
볼품없는 라이브러리에 렌즈를 사용하는 것이 좋습니다 :
import shapeless.lens case class Persona(serviceName : String, serviceId : String, sentMessages : Set[String]) // define the lens val messageLens = lens[Persona] >> 'sentMessages val existingPersona = Persona("store", "apple", Set("iPhone")) // When you need the new copy, by setting the value, val newPersona1 = messageLens.set(existingPersona)(Set.empty) // or by other operation based on current value. val newPersona2 = messageLens.modify(existingPersona)(_ + "iPad") // Results: // newPersona1: Persona(store,apple,Set()) // newPersona2: Persona(store,apple,Set(iPhone, iPad))
당신이 중첩 된 경우 수업을해야하는 경우에 또한,의 getter 및 setter 메소드 작성에 조금 지루한 될 수 있습니다. 이 렌즈 라이브러리를 사용하여 간단하게 할 수있는 좋은 기회가 될 것입니다.
또한 다음을 참조하십시오 :
-
==============================
5.난 당신이 중첩 된 경우 클래스에 깊이 값을 설정할 수 복잡한 렌즈를 수행하는 큰 라이브러리를 포함하지 않았다. 그것은이 scalaz 라이브러리에서 단 몇 줄의 코드입니다 밝혀 :
난 당신이 중첩 된 경우 클래스에 깊이 값을 설정할 수 복잡한 렌즈를 수행하는 큰 라이브러리를 포함하지 않았다. 그것은이 scalaz 라이브러리에서 단 몇 줄의 코드입니다 밝혀 :
/** http://stackoverflow.com/a/5597750/329496 */ case class Lens[A, B](get: A => B, set: (A, B) => A) extends ((A) => B) with Immutable { def apply(whole: A): B = get(whole) def mod(a: A, f: B => B) = set(a, f(this (a))) def compose[C](that: Lens[C, A]) = Lens[C, B]( c => this(that(c)), (c, b) => that.mod(c, set(_, b)) ) def andThen[C](that: Lens[B, C]) = that compose this }
그런 다음 깊이가 복사 기능 내장 사용하는 것보다 훨씬 더 쉽게 중첩 된 값을 설정 렌즈를 만들 수 있습니다. 여기에 큰 세트에 링크되어있는 경우 내 라이브러리 사용이 많이 중첩 된 값을 설정한다는 것을 복합 렌즈.
from https://stackoverflow.com/questions/7249396/how-to-clone-a-case-class-instance-and-change-just-one-field-in-scala by cc-by-sa and MIT license
'SCALA' 카테고리의 다른 글
[SCALA] 스칼라 : 어떻게 동적 객체와 반사를 사용하여 메서드 Invoke를 인스턴스화합니까? (0) | 2019.11.10 |
---|---|
[SCALA] 어떻게 스파크 2.0에서 단위 테스트를 작성하는? (0) | 2019.11.10 |
[SCALA] 어떻게 스칼라 2.9 일에서 "scala.sys.process"는 무엇입니까? (0) | 2019.11.10 |
[SCALA] => 수행하고 무엇 () => 스칼라의 평균 [중복] (0) | 2019.11.10 |
[SCALA] 간단한 경우 클래스에 대한 주문을 정의하기 쉬운 관용적 방법 (0) | 2019.11.10 |