ถอดรหัสเป็นคลาสแบบเคส
แมป JSON เข้ากับชนิดข้อมูลของคุณ
ถอดรหัสเป็นคลาสแบบเคส เป็นบทเรียน Scala for Backend Engineering & Functional Programming ฟรีบน CoddyKit นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Scala for Backend Engineering & Functional Programming และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Scala for Backend Engineering & Functional Programming มีบทเรียนทั้งหมด 4 บทเรียน
ตัวถอดรหัสจับคู่ JSON กับชนิดข้อมูล
Decoder[A] รู้วิธีอ่านค่า Json ให้เป็นชนิด Scala A
Circe มีตัวถอดรหัสสำหรับชนิดพื้นฐานและคอลเลกชันมาให้พร้อมใช้ และสามารถสร้างตัวถอดรหัสสำหรับคลาสกรณีของคุณโดยอัตโนมัติ
คลาสกรณีเป้าหมาย
สมมติว่า API ของคุณส่งระเบียนผู้ใช้กลับมา ให้จำลองโครงสร้างด้วยคลาสกรณีที่ชื่อฟิลด์ตรงกับคีย์ JSON
การใช้ชื่อที่ตรงกันทำให้ Circe สร้างตัวถอดรหัสได้โดยไม่ต้องเชื่อมโยงด้วยตนเอง
case class User(name: String, age: Int, admin: Boolean)การสร้างโดยอัตโนมัติ
นำเข้า io.circe.generic.auto._ แล้ว Circe จะสร้าง Decoder[User] โดยปริยายตามต้องการในทุกจุดที่จำเป็น
จากนั้นคุณเรียก decode[User] ได้โดยไม่ต้องเขียนโค้ดประกอบเพิ่มเติม
import io.circe.generic.auto._
import io.circe.parser.decode
val json = "{\"name\":\"Ada\",\"age\":36,\"admin\":true}"
val user = decode[User](json)
println(user) // Right(User(Ada,36,true))การสร้างแบบกึ่งอัตโนมัติ
เพื่อให้คอมไพล์เร็วขึ้นและควบคุมได้อย่างชัดเจน ให้ใช้ io.circe.generic.semiauto.deriveDecoder
คุณกำหนดตัวถอดรหัสเพียงครั้งเดียว โดยทั่วไปในออบเจ็กต์คู่หู แล้วนำอินสแตนซ์เดียวกันนั้นกลับมาใช้ซ้ำได้ทุกที่
import io.circe.Decoder
import io.circe.generic.semiauto._
object User {
implicit val dec: Decoder[User] = deriveDecoder[User]
}ความล้มเหลวในการถอดรหัส
หากฟิลด์ที่จำเป็นหายไปหรือมีชนิดไม่ถูกต้อง การถอดรหัสจะล้มเหลวพร้อม DecodingFailure
ความล้มเหลวนี้เก็บ ประวัติ ของการดำเนินการของเคอร์เซอร์ไว้ ทำให้ระบุได้อย่างแม่นยำว่าฟิลด์ใดเป็นสาเหตุของปัญหา
val bad = decode[User]("{\"name\":\"Ada\"}")
println(bad)
// Left(DecodingFailure at .age: Missing required field)ฟิลด์ที่ไม่บังคับในคลาส
กำหนดฟิลด์เป็น Option[A] เมื่อคีย์ JSON อาจไม่มีอยู่หรือมีค่า null
Circe จะถอดรหัสคีย์ที่หายไปเป็น None โดยอัตโนมัติ ดังนั้นคุณไม่จำเป็นต้องสร้างตัวถอดรหัสแบบกำหนดเองเพียงเพื่อรองรับค่าที่ไม่บังคับ
case class Account(id: Long, nickname: Option[String])
val a = decode[Account]("{\"id\":7}")
println(a) // Right(Account(7,None))ค่าเริ่มต้น
ค่าเริ่มต้นของคลาสกรณีสามารถเติมคีย์ JSON ที่หายไปได้ แต่จะทำได้เมื่อคุณใช้การสร้างแบบกำหนดค่าไว้ซึ่งเปิดใช้ค่าเริ่มต้น
โมดูล circe-generic-extras รองรับสิ่งนี้ผ่าน Configuration.default.withDefaults
import io.circe.generic.extras._
implicit val cfg: Configuration =
Configuration.default.withDefaults
@ConfiguredJsonCodec
case class Settings(theme: String = "dark")คลาสกรณีที่ซ้อนกัน
การถอดรหัสสามารถประกอบกันได้: หาก Circe ถอดรหัสชนิดของแต่ละฟิลด์ได้ ก็จะถอดรหัสคลาสที่ซ้อนคลาสกรณีอื่นได้เช่นกัน
การสร้างจะทำซ้ำโดยอัตโนมัติ ดังนั้นการนำเข้าเพียงครั้งเดียวก็รองรับโครงสร้างที่ซ้อนกันลึกได้
case class Address(city: String)
case class Person(name: String, address: Address)
val p = decode[Person](
"{\"name\":\"Ada\",\"address\":{\"city\":\"London\"}}")
println(p)เปลี่ยนชื่อฟิลด์
เมื่อคีย์ JSON แตกต่างจากชื่อใน Scala (เช่น snake_case) ให้ใช้การสร้างแบบกำหนดค่าด้วย Configuration.default.withSnakeCaseMemberNames
วิธีนี้จะแปลง created_at เป็นฟิลด์ Scala createdAt โดยไม่ต้องเขียนตัวถอดรหัสเอง
import io.circe.generic.extras._
implicit val cfg: Configuration =
Configuration.default.withSnakeCaseMemberNames
@ConfiguredJsonCodec
case class Event(createdAt: String)รวบรวมข้อผิดพลาด
โดยค่าเริ่มต้น การถอดรหัสจะหยุดทันทีเมื่อพบข้อผิดพลาดแรก แต่ decodeAccumulating จะรวบรวมความล้มเหลว ทั้งหมด ไว้ใน ValidatedNel
วิธีนี้มีประโยชน์สำหรับการตรวจสอบแบบฟอร์มที่ต้องการรายงานปัญหาทั้งหมดพร้อมกัน
import io.circe.Decoder
val result = Decoder[User]
.decodeAccumulating(json.hcursor)
// Validated[NonEmptyList[DecodingFailure], User]เลือกสไตล์การสร้าง
ใช้ auto สำหรับต้นแบบอย่างรวดเร็ว และใช้ semiauto สำหรับโค้ดใช้งานจริงที่ต้องการอินสแตนซ์คงที่และการคอมไพล์ที่เร็วขึ้น
เลือกใช้ generic-extras เมื่อจำเป็นต้องเปลี่ยนชื่อ กำหนดค่าเริ่มต้น หรือใช้ตัวจำแนก
ตรวจสอบความเข้าใจ
ทดสอบความเข้าใจของคุณเกี่ยวกับการถอดรหัสเป็นคลาสกรณี
สรุปทบทวน
Decoder[A] แปลง JSON เป็นค่าที่มีชนิดข้อมูล ใช้ generic.auto หรือ semiauto.deriveDecoder สำหรับคลาสกรณีที่ชื่อสอดคล้องกับคีย์
คีย์ที่หายไปจะถอดรหัสฟิลด์ Option เป็น None ส่วน generic-extras เพิ่มการกำหนดค่าเริ่มต้นและการเปลี่ยนชื่อ และ decodeAccumulating จะรวบรวมข้อผิดพลาดทั้งหมด
คำถามที่พบบ่อย
บทเรียน “ถอดรหัสเป็นคลาสแบบเคส” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “ถอดรหัสเป็นคลาสแบบเคส” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Scala for Backend Engineering & Functional Programming ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Scala for Backend Engineering & Functional Programming มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “ถอดรหัสเป็นคลาสแบบเคส”
แมป JSON เข้ากับชนิดข้อมูลของคุณ คุณปฏิบัติ Scala for Backend Engineering & Functional Programming ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Scala for Backend Engineering & Functional Programming หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Scala for Backend Engineering & Functional Programming บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน
บทเรียน “ถอดรหัสเป็นคลาสแบบเคส” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Scala for Backend Engineering & Functional Programming นี้ได้ไหม
ได้ บทเรียน Scala for Backend Engineering & Functional Programming ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- แยกวิเคราะห์ JSON
- ถอดรหัสเป็นคลาสแบบเคส
- เข้ารหัสเป็น JSON
- ตัวเข้ารหัสและถอดรหัสแบบกำหนดเอง