Własne kodeki
Obsłuży Pan/Pani nietypowe struktury.
Własne kodeki to bezpłatna lekcja Scala for Backend Engineering & Functional Programming na CoddyKit. To lekcja 4 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Scala for Backend Engineering & Functional Programming, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Scala for Backend Engineering & Functional Programming zawiera 4 lekcji w sumie.
Kiedy potrzebny jest własny kodek
Wyprowadzanie obsługuje typowe przypadki, ale czasami JSON nie odzwierciedla klasy przypadku: może używać starszych nazw pól, kodowanych wyliczeń lub formatów takich jak znaczniki czasu.
Wtedy należy ręcznie napisać obiekt Decoder, Encoder albo oba.
Dekoder z kursora
Najbardziej jawnym sposobem utworzenia dekodera jest użycie Decoder.instance, który otrzymuje obiekt HCursor.
Po polach porusza się za pomocą downField i as, zwracając wartość Either.
import io.circe.Decoder
case class User(name: String, age: Int)
implicit val dec: Decoder[User] = Decoder.instance { c =>
for {
n <- c.downField("full_name").as[String]
a <- c.downField("years").as[Int]
} yield User(n, a)
}Pomocnicze metody forProductN
W przypadku prostych mapowań bardziej zwięzła jest metoda Decoder.forProduct2: należy podać klucze JSON i przekazać konstruktor.
Pomocnicze metody są dostępne od forProduct1 aż po wersje obsługujące wiele argumentów.
import io.circe.Decoder
implicit val dec: Decoder[User] =
Decoder.forProduct2("full_name", "years")(User.apply)Ręczne tworzenie enkodera
Odwzoruj dekoder za pomocą Encoder.instance, tworząc obiekt Json z pól.
Możesz też użyć Encoder.forProduct2, aby jednym wywołaniem zmapować wartości z powrotem na wybrane klucze JSON.
import io.circe.Encoder
implicit val enc: Encoder[User] =
Encoder.forProduct2("full_name", "years")(u =>
(u.name, u.age))Przekształcanie istniejących kodeków
Rzadko zaczyna się od zera. map dostosowuje wynik dekodera, a contramap dostosowuje dane wejściowe enkodera.
emap działa podobnie jak map, ale może zakończyć się niepowodzeniem, zwracając Either[String, A] do celów walidacji.
import io.circe.Decoder
case class Age(value: Int)
implicit val dec: Decoder[Age] =
Decoder[Int].emap { i =>
if (i >= 0) Right(Age(i)) else Left("negative age")
}Kodeki dla wyliczeń
Zapieczętowane cechy z obiektami przypadku służą do modelowania wyliczeń. Każdy przypadek należy zakodować jako ciąg znaków będący etykietą, a podczas dekodowania dopasować z powrotem ten ciąg.
emap zamienia nieznaną etykietę w czytelny błąd dekodowania.
sealed trait Role
case object Admin extends Role
case object Guest extends Role
implicit val dec: Decoder[Role] = Decoder[String].emap {
case "admin" => Right(Admin)
case "guest" => Right(Guest)
case other => Left(s"unknown role: $other")
}Ponowne kodowanie wyliczenia
Połącz dekoder wyliczenia z enkoderem używającym contramap, który renderuje każdy przypadek jako jego etykietę.
Teraz zapieczętowana cecha jest kodowana i dekodowana bez utraty informacji jako zwykły ciąg znaków w JSON.
import io.circe.Encoder
implicit val enc: Encoder[Role] = Encoder[String].contramap {
case Admin => "admin"
case Guest => "guest"
}Własny kodek dla dat
Circe nie zawiera wbudowanych kodeków java.time w module core, dlatego daty są klasycznym przypadkiem zastosowania własnego kodeka.
Dekoduj i koduj za pomocą formatu ciągu ISO.
import java.time.LocalDate
import io.circe.{Decoder, Encoder}
implicit val dec: Decoder[LocalDate] =
Decoder[String].map(LocalDate.parse)
implicit val enc: Encoder[LocalDate] =
Encoder[String].contramap(_.toString)Łączenie w kodek
Gdy masz oba kierunki, połącz je w jeden obiekt Codec[A] za pomocą Codec.from(decoder, encoder).
Dzięki temu w zakresie wystarczy jeden implicit zamiast dwóch osobnych.
import io.circe.Codec
implicit val roleCodec: Codec[Role] =
Codec.from(dec, enc)Dyskryminatory dla ADT
W przypadku zapieczętowanych hierarchii zawierających dane biblioteka circe-generic-extras dodaje pole dyskryminatora zamiast obiektu opakowującego.
Skonfiguruj je raz, a następnie wyprowadź kodeki dla całego ADT.
import io.circe.generic.extras._
implicit val cfg: Configuration =
Configuration.default.withDiscriminator("type")
@ConfiguredJsonCodec sealed trait Shape
@ConfiguredJsonCodec case class Circle(r: Double) extends ShapeZakres i priorytet implicitów
Ręcznie napisany implicit kodeka ma pierwszeństwo przed wyprowadzaniem, o ile znajduje się w zakresie. Umieść go w obiekcie towarzyszącym, aby zawsze był znajdowany.
Unikaj jednoczesnego importowania auto._ i ręcznej instancji dla tego samego typu, aby zapobiec niejednoznaczności.
Szybki test
Sprawdź swoją wiedzę na temat własnych kodeków.
Podsumowanie
Własne kodeki obsługują JSON, który nie pasuje do typów. Twórz je za pomocą Decoder.instance, forProductN albo przekształcaj istniejące kodeki za pomocą map, contramap i emap.
Wyliczenia i daty to częste przypadki; połącz oba kierunki za pomocą Codec.from, a dla ADT używaj dyskryminatorów.
Ucz się Scala dzięki korepetycjom AI — za darmo
Pisz i uruchamiaj kod w przeglądarce, otrzymuj natychmiastową pomoc od korepetytora AI dostępnego 24/7 i kontynuuj naukę w sieci lub w aplikacji.
- Kursy
- 39
- Lekcje
- 143
Często zadawane pytania
Czy lekcja „Własne kodeki” jest bezpłatna?
Tak — pełny tekst „Własne kodeki” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Scala for Backend Engineering & Functional Programming, przejdź na CoddyKit PRO. Kurs Scala for Backend Engineering & Functional Programming zawiera 4 lekcji w sumie.
Co nauczysz się w „Własne kodeki”?
Obsłuży Pan/Pani nietypowe struktury. Ćwiczysz Scala for Backend Engineering & Functional Programming z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć Scala for Backend Engineering & Functional Programming?
Nie wymagamy żadnego doświadczenia. Scala for Backend Engineering & Functional Programming w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 4 z 4.
Ile czasu zajmuje lekcja „Własne kodeki”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji Scala for Backend Engineering & Functional Programming?
Tak. Każda lekcja Scala for Backend Engineering & Functional Programming zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.