ตัวแทนสำหรับ Preferences พร็อพเพอร์ตีที่ใช้ Map และการบันทึก
ประยุกต์ใช้ตัวแทนกับ SharedPreferences การจัดเก็บด้วย Map และการบันทึกเพื่อตรวจสอบ
ตัวแทนสำหรับ Preferences พร็อพเพอร์ตีที่ใช้ Map และการบันทึก เป็นบทเรียน Kotlin Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Kotlin Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Kotlin Academy มีบทเรียนทั้งหมด 4 บทเรียน
พร็อพเพอร์ตีที่ใช้แมปเป็นแหล่งข้อมูลเบื้องหลัง
Kotlin อนุญาตให้มอบหมายพร็อพเพอร์ตีให้กับ Map ได้โดยตรง การอ่านพร็อพเพอร์ตีจะค้นหาชื่อของพร็อพเพอร์ตีในแมป
class User(map: Map<String, Any?>) {
val name: String by map
val age: Int by map
}
fun main() {
val u = User(mapOf("name" to "Alice", "age" to 30))
println(u.name) // Alice
println(u.age) // 30
}ดีลีต MutableMap
สำหรับพร็อพเพอร์ตีที่เปลี่ยนแปลงได้ ให้มอบหมายไปยัง MutableMap แล้วการเปลี่ยนแปลงจะอัปเดตแมปที่อยู่เบื้องหลัง
class Settings(private val map: MutableMap<String, Any?> = mutableMapOf()) {
var theme: String by map
var fontSize: Int by map
}
fun main() {
val s = Settings()
s.theme = "dark"
s.fontSize = 16
println(s.theme) // dark
println(s.fontSize) // 16
}การดีซีเรียลไลซ์ JSON ด้วยดีลีตแมป
แยกวิเคราะห์แมปที่มีลักษณะคล้าย JSON แล้วเปิดเผยฟิลด์ต่าง ๆ เป็นพร็อพเพอร์ตีที่มีชนิดข้อมูล โดยใช้การมอบหมายให้แมป เหมาะอย่างยิ่งสำหรับข้อมูลแบบไดนามิก
class ApiResponse(data: Map<String, Any?>) {
val id: Int by data
val title: String by data
val published: Boolean by data
}
fun main() {
val response = ApiResponse(mapOf("id" to 1, "title" to "Kotlin Rocks", "published" to true))
println(response.title) // Kotlin Rocks
println(response.published) // true
}รูปแบบดีลีตสำหรับการบันทึกข้อมูลการทำงาน
ห่อดีลีตใด ๆ ด้วยการบันทึกข้อมูลการทำงาน เพื่อ ติดตามการอ่านและการเขียนทุกครั้งอย่างโปร่งใสในพร็อพเพอร์ตีที่ได้รับการมอบหมายทั้งหมด
import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty
class Logged<T>(private var v: T) : ReadWriteProperty<Any?, T> {
override fun getValue(t: Any?, p: KProperty<*>): T {
println("[READ] ${p.name} = $v"); return v
}
override fun setValue(t: Any?, p: KProperty<*>, value: T) {
println("[WRITE] ${p.name}: $v -> $value"); v = value
}
}
var config: String by Logged("default")
fun main() { println(config); config = "production" }การรวมแมปกับการบันทึกข้อมูลการทำงาน
วางตัวห่อสำหรับการบันทึกข้อมูลการทำงานไว้รอบการมอบหมายให้แมป เพื่อให้ตรวจสอบการเข้าถึงพร็อพเพอร์ตีแบบไดนามิกได้อย่างครบถ้วน
import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty
class TrackedMap(private val map: MutableMap<String,Any?> = mutableMapOf()) {
inner class Delegate<T> : ReadWriteProperty<Any?,T> {
@Suppress("UNCHECKED_CAST")
override fun getValue(t:Any?,p:KProperty<*>): T {
val v = map[p.name] as T; println("read ${p.name}=$v"); return v
}
override fun setValue(t:Any?,p:KProperty<*>,value:T) {
println("write ${p.name}=$value"); map[p.name]=value
}
}
var host: String by Delegate()
}
fun main() { val m=TrackedMap(); m.host="localhost"; println(m.host) }ดีลีตลักษณะเดียวกับ SharedPreferences
ดีลีตที่จัดเก็บค่าไว้ในแมปเบื้องหลังเพื่อจำลอง SharedPreferences โดยสามารถปรับใช้กับการตั้งค่าจริงของ Android ได้ด้วยการเปลี่ยนแมปเป็นการเรียกใช้การตั้งค่าจริง
import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty
val prefs = mutableMapOf<String, Any?>()
fun <T> pref(default: T): ReadWriteProperty<Any?, T> = object : ReadWriteProperty<Any?, T> {
@Suppress("UNCHECKED_CAST")
override fun getValue(t: Any?, p: KProperty<*>): T = prefs.getOrDefault(p.name, default) as T
override fun setValue(t: Any?, p: KProperty<*>, value: T) { prefs[p.name] = value }
}
object UserPrefs {
var username: String by pref("Guest")
var isDarkMode: Boolean by pref(false)
}
fun main() {
println(UserPrefs.username) // Guest
UserPrefs.username = "Alice"
println(UserPrefs.username) // Alice
}ฟังก์ชันช่วยจัดการการตั้งค่าที่มีชนิดข้อมูล
สร้างฟังก์ชันช่วยที่มีชนิดข้อมูลเฉพาะสำหรับการตั้งค่าพื้นฐานแต่ละชนิด เพื่อให้จุดเรียกใช้สะอาดและอ่านง่ายขึ้น
import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty
val store = mutableMapOf<String,Any?>()
fun stringPref(default: String) = object : ReadWriteProperty<Any?,String> {
@Suppress("UNCHECKED_CAST")
override fun getValue(t:Any?,p:KProperty<*>) = store.getOrDefault(p.name, default) as String
override fun setValue(t:Any?,p:KProperty<*>,v:String) { store[p.name]=v }
}
fun intPref(default: Int) = object : ReadWriteProperty<Any?,Int> {
@Suppress("UNCHECKED_CAST")
override fun getValue(t:Any?,p:KProperty<*>) = store.getOrDefault(p.name, default) as Int
override fun setValue(t:Any?,p:KProperty<*>,v:Int) { store[p.name]=v }
}
object Prefs {
var name: String by stringPref("default")
var count: Int by intPref(0)
}
fun main() { Prefs.name="Bob"; Prefs.count=5; println("${Prefs.name}: ${Prefs.count}") }ดีลีตบันทึกการตรวจสอบ
บันทึกการเปลี่ยนแปลงพร็อพเพอร์ตีทุกครั้งพร้อมเวลาประทับลงในรายการบันทึกการตรวจสอบ เหมาะสำหรับสถานการณ์ที่ต้องปฏิบัติตามข้อกำหนดหรือการแก้ไขข้อบกพร่อง
import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty
val audit = mutableListOf<String>()
class AuditDelegate<T>(private var v: T) : ReadWriteProperty<Any?, T> {
override fun getValue(t:Any?,p:KProperty<*>) = v
override fun setValue(t:Any?,p:KProperty<*>,value:T) {
audit += "[${System.currentTimeMillis()}] ${p.name}: $v -> $value"
v = value
}
}
var price: Double by AuditDelegate(9.99)
fun main() {
price = 12.99
price = 11.49
audit.forEach(::println)
}การตรวจสอบความถูกต้องร่วมกับการจัดเก็บในแมป
ผสานการจัดเก็บในแมปเข้ากับการตรวจสอบความถูกต้อง โดยปฏิเสธค่าที่ไม่ถูกต้องก่อนเขียนลงในแมป
import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty
val data = mutableMapOf<String, Any?>()
fun positiveInt(default: Int): ReadWriteProperty<Any?,Int> = object : ReadWriteProperty<Any?,Int> {
@Suppress("UNCHECKED_CAST")
override fun getValue(t:Any?,p:KProperty<*>)=data.getOrDefault(p.name,default) as Int
override fun setValue(t:Any?,p:KProperty<*>,v:Int){
require(v>=0){"${p.name} must be >= 0"}
data[p.name]=v
}
}
object Inventory { var stock: Int by positiveInt(100) }
fun main(){
Inventory.stock=50; println(Inventory.stock)
try { Inventory.stock=-1 } catch(e:Exception){ println(e.message) }
}รูปแบบการประกอบดีลีต
ประกอบพฤติกรรมของดีลีตหลายรายการโดยใช้ API ลักษณะเดียวกับตัวสร้าง เริ่มจากดีลีตพื้นฐาน แล้วเพิ่มการบันทึกข้อมูลการทำงาน การตรวจสอบความถูกต้อง หรือการแคชทีละชั้น
import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty
fun <T> ReadWriteProperty<Any?,T>.withLogging(): ReadWriteProperty<Any?,T> {
val base = this
return object : ReadWriteProperty<Any?,T> {
override fun getValue(t:Any?,p:KProperty<*>): T {
val v = base.getValue(t,p); println("get ${p.name}=$v"); return v
}
override fun setValue(t:Any?,p:KProperty<*>,v:T){
println("set ${p.name}=$v"); base.setValue(t,p,v)
}
}
}การใช้งานจริง: รูปแบบออบเจ็กต์การตั้งค่า
ใช้การมอบหมายให้แมปเพื่อสร้างออบเจ็กต์การตั้งค่าจากแหล่งข้อมูลภายนอก เช่น ตัวแปรสภาพแวดล้อมหรือไฟล์การตั้งค่า JSON
class AppConfig(private val raw: Map<String, Any?>) {
val host: String by raw
val port: Int by raw
val debug: Boolean by raw
}
fun main() {
val env = mapOf("host" to "0.0.0.0", "port" to 8080, "debug" to true)
val cfg = AppConfig(env)
println("${cfg.host}:${cfg.port} debug=${cfg.debug}")
}ตรวจสอบความเข้าใจ
จะเกิดอะไรขึ้นเมื่อคุณมอบหมายพร็อพเพอร์ตีให้กับ Map
สรุปทบทวน
ดีลีตช่วยให้ใช้รูปแบบที่ทรงพลังได้หลายแบบ ได้แก่ การมอบหมายให้แมปสำหรับข้อมูลแบบไดนามิกหรือ JSON การคงอยู่ของข้อมูลในลักษณะ SharedPreferences การบันทึกการตรวจสอบเพื่อรองรับข้อกำหนด และการตรวจสอบความถูกต้องที่ประกอบใช้งานได้ โดยไม่ต้องเปลี่ยนจุดเรียกใช้
คำถามที่พบบ่อย
บทเรียน “ตัวแทนสำหรับ Preferences พร็อพเพอร์ตีที่ใช้ Map และการบันทึก” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “ตัวแทนสำหรับ Preferences พร็อพเพอร์ตีที่ใช้ Map และการบันทึก” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Kotlin Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Kotlin Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “ตัวแทนสำหรับ Preferences พร็อพเพอร์ตีที่ใช้ Map และการบันทึก”
ประยุกต์ใช้ตัวแทนกับ SharedPreferences การจัดเก็บด้วย Map และการบันทึกเพื่อตรวจสอบ คุณปฏิบัติ Kotlin Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Kotlin Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Kotlin Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน
บทเรียน “ตัวแทนสำหรับ Preferences พร็อพเพอร์ตีที่ใช้ Map และการบันทึก” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Kotlin Academy นี้ได้ไหม
ได้ บทเรียน Kotlin Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- by lazy: เจาะลึกการเริ่มต้นแบบเลื่อนเวลา
- ตัวแทน observable และ vetoable
- การเขียนตัวแทน ReadWriteProperty แบบกำหนดเอง
- ตัวแทนสำหรับ Preferences พร็อพเพอร์ตีที่ใช้ Map และการบันทึก