언급 한 두 가지 방식은 각각 기능적 및 OO 패러다임에 속합니다. 스칼라에서 사례 클래스로 표현되는 추상 데이터 유형으로 기능적 분해를 선호하는 경우 복사 방법을 선택하십시오. 돌연변이 체를 사용하는 것은 좋은 방법이 아닙니다. Java/C#/C++ 방식으로 다시 돌아갈 수 있습니다.
case class Person(name: String, age: String)
후 더 consise 인 ADT 경우 클래스를 만드는 한편
같은 :
class Person(_name: String, _age: String) {
var name = _name
var age = _a
def changeName(newName: String): Unit = { name = newName }
// ... and so on
}
(안 최고의 필수적 코드가 짧아 질 수 있지만, 삭제할 수 있습니다).
class Person(val name: String,
val age: String) {
def changeName(newName: String): Unit = new Person(newName, age)
// ... and so on
}
그러나 여전히 경우 클래스의 방법은 더 consise입니다 : 원인의
는 각 호출에 새로운 개체를 반환, 뮤 테이터 또 다른 방법이있다.
그리고 동시/병렬 프로그래밍으로 넘어 간다면, 불변 값을 가진 기능적 개념이 훨씬 더 좋음을 알 수있을 것이며, 현재 객체의 상태를 추측 할 수 있습니다. 니아에
업데이트
덕분에, 두 가지를 언급하는 것을 잊었다.
렌즈 가장 기본적인 수준에서
는, 렌즈는 다음과 같이 불변 데이터에 대한 getter 및 setter의 일종과 같습니다 그것은
case class Lens[A,B](get: A => B, set: (A,B) => A) {
def apply(a: A) = get(a)
// ...
}
즉. 렌즈는 get과 set의 두 가지 기능을 포함하는 객체입니다. get은 A를 취해 B를 반환합니다. set은 A와 B를 취하여 A를 반환합니다. B가 A에 포함 된 값이라는 것을 쉽게 알 수 있습니다. 인스턴스를 전달하면 값을 반환합니다. 우리가 A와 B를 통과 시키면 A에서 값 B를 갱신하고 변경을 반영하는 새로운 A를 리턴합니다. 편의상 get에 별칭이 적용됩니다.Scalaz 렌즈 케이스 클래스이 하나가 ofcause의 shapeless 라이브러리라는 기록에서 유래
기록
에 좋은 intro 있습니다. 연관성의 HLists로 모델화 된 확장 가능한 레코드의 구현. 키는 싱글 톤 유형을 사용하여 인코딩되며 해당 값의 유형을 완전히 결정합니다 (예 : github에서).
object author extends Field[String]
object title extends Field[String]
object price extends Field[Double]
object inPrint extends Field[Boolean]
val book =
(author -> "Benjamin Pierce") ::
(title -> "Types and Programming Languages") ::
(price -> 44.11) ::
HNil
// Read price field
val currentPrice = book.get(price) // Inferred type is Double
currentPrice == 44.11
// Update price field, relying on static type of currentPrice
val updated = book + (price -> (currentPrice+2.0))
// Add a new field
val extended = updated + (inPrint -> true)
변경 사항을 얻으려면 Event Sourcing을 사용할 수 있습니다. –