การเขียนตัวแทน ReadWriteProperty แบบกำหนดเอง
สร้างตัวแทนพร็อพเพอร์ตีแบบกำหนดเองตั้งแต่ต้นด้วย ReadWriteProperty
การเขียนตัวแทน ReadWriteProperty แบบกำหนดเอง เป็นบทเรียน Kotlin Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Kotlin Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Kotlin Academy มีบทเรียนทั้งหมด 4 บทเรียน
อินเทอร์เฟซ ReadWriteProperty
ตัวแทนแบบกำหนดเองจะใช้งาน ReadWriteProperty<ThisRef, T> พร้อมตัวดำเนินการ getValue และ setValue
import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty
class SimpleDelegate<T>(private var value: T) : ReadWriteProperty<Any?, T> {
override fun getValue(thisRef: Any?, property: KProperty<*>): T = value
override fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
this.value = value
}
}
var x: Int by SimpleDelegate(0)
fun main() { x = 42; println(x) }ReadOnlyProperty สำหรับ val
สำหรับพร็อพเพอร์ตี val แบบอ่านอย่างเดียว ให้ใช้งาน ReadOnlyProperty<ThisRef, T> โดยมีเพียง getValue
import kotlin.properties.ReadOnlyProperty
import kotlin.reflect.KProperty
class Constant<T>(private val value: T) : ReadOnlyProperty<Any?, T> {
override fun getValue(thisRef: Any?, property: KProperty<*>): T = value
}
val pi: Double by Constant(3.14159)
fun main() { println(pi) }ใช้ thisRef สำหรับบริบท
thisRef ช่วยให้ตัวแทนเข้าถึงออบเจ็กต์ที่ครอบอยู่ได้ ทำให้สามารถทำงานโดยคำนึงถึงบริบท
import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty
class LoggingDelegate<T>(private var v: T) : ReadWriteProperty<Any?, T> {
override fun getValue(thisRef: Any?, property: KProperty<*>): T {
println("[${thisRef?.javaClass?.simpleName}] get ${property.name} = $v")
return v
}
override fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
println("[${thisRef?.javaClass?.simpleName}] set ${property.name} = $value")
v = value
}
}
class Config { var host: String by LoggingDelegate("localhost") }
fun main() { val c = Config(); c.host = "prod.example.com"; println(c.host) }ตัวแทนตัวเลขแบบจำกัดช่วง
ตัวแทนที่จำกัดค่าตัวเลขให้อยู่ในช่วงหนึ่ง และบังคับใช้เงื่อนไขคงที่อย่างโปร่งใส
import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty
class Clamped(private val min: Int, private val max: Int, initial: Int) : ReadWriteProperty<Any?, Int> {
private var v = initial.coerceIn(min, max)
override fun getValue(t: Any?, p: KProperty<*>) = v
override fun setValue(t: Any?, p: KProperty<*>, value: Int) {
v = value.coerceIn(min, max)
}
}
var brightness: Int by Clamped(0, 255, 128)
fun main() {
brightness = 300; println(brightness) // 255
brightness = -5; println(brightness) // 0
brightness = 100; println(brightness) // 100
}ตัวแทนแคชค่าที่อาจเป็น null
ตัวแทนที่คำนวณค่าเพียงครั้งเดียวและแคชไว้ โดยสามารถทำให้แคชไม่ถูกต้องได้ด้วยการกำหนดค่าเป็น null
import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty
class CachedNullable<T>(private val compute: () -> T) : ReadWriteProperty<Any?, T?> {
private var cache: T? = null
override fun getValue(t: Any?, p: KProperty<*>): T? = cache ?: compute().also { cache = it }
override fun setValue(t: Any?, p: KProperty<*>, value: T?) { cache = value }
}
var expensiveResult: Int? by CachedNullable { (1..1000).sum() }
fun main() {
println(expensiveResult) // computed
println(expensiveResult) // cached
expensiveResult = null
println(expensiveResult) // recomputed
}ตัวแทนที่ปลอดภัยต่อเธรดด้วย @Synchronized
เพิ่มความปลอดภัยระหว่างเธรดให้ตัวแทนด้วย @Synchronized หรือออบเจ็กต์ล็อกภายใน
import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty
class SynchronizedDelegate<T>(private var v: T) : ReadWriteProperty<Any?, T> {
@Synchronized
override fun getValue(t: Any?, p: KProperty<*>) = v
@Synchronized
override fun setValue(t: Any?, p: KProperty<*>, value: T) { v = value }
}
var counter: Int by SynchronizedDelegate(0)
fun main() { counter = 99; println(counter) }รูปแบบฟังก์ชันโรงงานของตัวแทน
เปิดเผยตัวแทนผ่านฟังก์ชันส่วนขยายที่ส่งคืนออบเจ็กต์ตัวแทน โดยทำตามรูปแบบของไลบรารีมาตรฐาน
import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty
fun <T> logged(initial: T): ReadWriteProperty<Any?, T> = object : ReadWriteProperty<Any?, T> {
var v = initial
override fun getValue(t: Any?, p: KProperty<*>): T { println("get ${p.name}"); return v }
override fun setValue(t: Any?, p: KProperty<*>, value: T) { println("set ${p.name}=$value"); v = value }
}
var name: String by logged("world")
fun main() { println(name); name = "Kotlin" }ตัวแทนพร้อมข้อมูลเมทาดาทาของ KProperty
อาร์กิวเมนต์ KProperty ให้ชื่อพร็อพเพอร์ตีและคำอธิบายประกอบ ซึ่งมีประโยชน์สำหรับเฟรมเวิร์กการบันทึกข้อมูลหรือ ORM
import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty
class AuditDelegate<T>(private var v: T) : ReadWriteProperty<Any?, T> {
private val history = mutableListOf<String>()
override fun getValue(t: Any?, p: KProperty<*>) = v
override fun setValue(t: Any?, p: KProperty<*>, value: T) {
history.add("${p.name}: $v -> $value")
v = value
}
fun printHistory() = history.forEach(::println)
}
var status: String by AuditDelegate("idle").also { /* expose audit */ }ตัวดำเนินการ provideDelegate
provideDelegate ช่วยให้ตัวแทนดักจับการตั้งค่าการมอบหมาย ตรวจสอบชื่อพร็อพเพอร์ตีหรือคำอธิบายประกอบได้ในเวลาเริ่มต้น
import kotlin.properties.ReadOnlyProperty
import kotlin.reflect.KProperty
class ValidatedDelegate<T>(private val v: T) {
operator fun provideDelegate(t: Any?, p: KProperty<*>): ReadOnlyProperty<Any?, T> {
require(p.name.isNotBlank()) { "Property name must not be blank" }
return ReadOnlyProperty { _, _ -> v }
}
}
val greeting: String by ValidatedDelegate("Hello")
fun main() { println(greeting) }เปรียบเทียบแนวทาง
ตัวแทนแบบกำหนดเองกับ observable/vetoable: ใช้ตัวแทนในตัวสำหรับรูปแบบการตอบสนองแบบง่าย และเขียนตัวแทนแบบกำหนดเองสำหรับเงื่อนไขคงที่ที่ซับซ้อน การแคช หรือการทำงานที่คำนึงถึงบริบท
// Built-in: simple change notification
import kotlin.properties.Delegates
var simple: Int by Delegates.observable(0) { _,_,v -> println("changed: $v") }
// Custom: clamping + logging
var complex: Int by run {
object : kotlin.properties.ReadWriteProperty<Any?,Int> {
var v = 0
override fun getValue(t:Any?,p:kotlin.reflect.KProperty<*>)=v
override fun setValue(t:Any?,p:kotlin.reflect.KProperty<*>,value:Int){
println("clamping $value"); v=value.coerceIn(0,100)
}
}
}
fun main() { simple=5; complex=200; println(complex) }ภาคปฏิบัติ: ดีลีเกตของ SharedPreferences
รูปแบบที่ใช้กันทั่วไปใน Android: มอบหมายพร็อพเพอร์ตีให้กับ SharedPreferences เพื่อให้การอ่านและการเขียนถูกบันทึกลงดิสก์โดยอัตโนมัติ
// Pseudocode (no Android runtime here)
class PrefDelegate(private val key: String, private val default: String) {
// In real Android code:
// override fun getValue(...) = prefs.getString(key, default) ?: default
// override fun setValue(...) { prefs.edit().putString(key, value).apply() }
fun getValue(): String = default // simplified
}
fun main() {
val delegate = PrefDelegate("user_name", "Guest")
println(delegate.getValue())
}ตรวจสอบความเข้าใจ
ดีลีตสำหรับอ่านและเขียนต้องใช้อินเทอร์เฟซใด
สรุปทบทวน
ดีลีตแบบกำหนดเองใช้งาน ReadWriteProperty (หรือ ReadOnlyProperty) และสามารถซ่อนการบันทึกข้อมูลการทำงาน การแคช การตรวจสอบความถูกต้อง การจำกัดค่า หรือการจัดเก็บบนแพลตฟอร์มไว้เบื้องหลังอินเทอร์เฟซพร็อพเพอร์ตีที่ใช้งานได้อย่างโปร่งใส
เรียนรู้ Kotlin ด้วย AI tutor — ฟรี
เขียนและเรียกใช้โค้ดจริงในเบราว์เซอร์ของคุณ รับความช่วยเหลือทันทีจาก AI tutor 24/7 และเรียนรู้ต่อจากที่คุณหยุดบนเว็บหรือในแอป
- คอร์ส
- 51
- บทเรียน
- 203
คำถามที่พบบ่อย
บทเรียน “การเขียนตัวแทน ReadWriteProperty แบบกำหนดเอง” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “การเขียนตัวแทน ReadWriteProperty แบบกำหนดเอง” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Kotlin Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Kotlin Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “การเขียนตัวแทน ReadWriteProperty แบบกำหนดเอง”
สร้างตัวแทนพร็อพเพอร์ตีแบบกำหนดเองตั้งแต่ต้นด้วย ReadWriteProperty คุณปฏิบัติ Kotlin Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Kotlin Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Kotlin Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน
บทเรียน “การเขียนตัวแทน ReadWriteProperty แบบกำหนดเอง” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Kotlin Academy นี้ได้ไหม
ได้ บทเรียน Kotlin Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- by lazy: เจาะลึกการเริ่มต้นแบบเลื่อนเวลา
- ตัวแทน observable และ vetoable
- การเขียนตัวแทน ReadWriteProperty แบบกำหนดเอง
- ตัวแทนสำหรับ Preferences พร็อพเพอร์ตีที่ใช้ Map และการบันทึก