재귀 유형
10688 단어 functionalscalaadt
Scala : JSON 표현에서 순환 참조 문제가 발생했습니다.
직렬화 및 역직렬화에 Gson을 사용했지만(자세한 내용은 설명하지 않음) 언어 생태계 내에서 모델을 표현하는 방법은 무엇입니까?
나는 Gson 문서를 따를 수 있고 pojos (case classes이 좋습니다)를 사용할 수 있지만 더 유연한 것이 필요했습니다.
정수, 문자열, 큰 숫자 등과 같은 기본 언어를 사용하기로 결정했습니다.
그래서 나는 그것을 다루기 위해 몇 가지 유형을 만들었습니다.
type unroll[+A] = A
type JValue = unroll[_ <: Any]
type JArray = Seq[JValue]
type JObject = String Map JValue
나쁘지 않습니다. 복잡한 객체를
JValue
변수에 담을 수 있습니다.val data: JValue = Map(
"x" -> 3,
"y" -> 4,
"name" -> "test",
"list" -> Seq("zero", 1, 2, 3, true),
)
그러나 다음과 같은 이상한 일이 일어나기 시작했습니다.
val element: JValue = <data>This is an XML node</data>
그것은 충돌해야합니다! 그러나
NodeSeq
는 Any
의 하위 클래스이기 때문에 그렇지 않습니다.더 엄격한 것이 필요했습니다.
도티 입력
이제 시도했습니다 Scala 3, codename Dotty .
내 첫 번째 실패한 시도는 다음과 같습니다.
type JNull = Unit
type JValue = Int | BigDecimal | String | Boolean | JNull | Seq[JValue] | String Map JValue
그리고 Dotty는 내 계획에 제동을 걸었습니다.
Illegal cyclic type reference: alias Map[Int | BigDecimal | String | Boolean | JNull | Seq[JValue] | String, JValue] of type JValue refers back to the type itself.
그런 다음 this strange solution을 쳤습니다.
type Rec[F[_], A] = A match {
case Int => Int | F[Rec[F, Int]]
case _ => A | F[Rec[F, A]]
}
Jasper M은 Scalatype erasure를 활용하여 런타임
LazyRef
을 생성할 것을 제안합니다. 그래서 나는 조언을 따랐다.type JNull = Unit
type JPrimitive = Int | BigDecimal | String | Boolean | JNull
type Rec[JArray[_], JObject[_], A] = A match
case JPrimitive => JPrimitive | JArray[Rec[JArray, JObject, JPrimitive]] | JObject[Rec[JArray, JObject, JPrimitive]]
case _ => A | JArray[Rec[JArray, JObject, A]] | JObject[Rec[JArray, JObject, A]]
type JValue = Rec[Seq, [A] =>> String Map A, JPrimitive]
그리고 보이스 라! 그것은 꽤 잘 작동합니다!
// Okay, unit represents null
var x: JValue = ()
// Also okay
x = true
// OMG! Still okay!
x = Map(
"x" -> 3,
"y" -> 4,
"name" -> "test",
"list" -> Seq("zero", 1, 2, 3, true),
)
// It throws an exception
x = <data>nope</data>
// If -Yexplicit-nulls is enabled, it throws an exception too
x = null
이제
JValue
는 훨씬 더 엄격해지고 WeakRef
는 재귀 유형을 가능하게 했습니다.
Reference
이 문제에 관하여(재귀 유형), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/cacilhas/recursive-types-32je텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)