Delegates til indstillinger, map-baserede egenskaber og logning
Anvend delegates til SharedPreferences, map-lagring og audit-logning.
Delegates til indstillinger, map-baserede egenskaber og logning er en gratis Kotlin Academy-lektion på CoddyKit. Dette er lektion 4 af 4. Du kan læse alle 3 lektioner i dette læringsspor gratis i deres fulde længde — derefter låser CoddyKit PRO alle lektioner op samt praktiske øvelser med en indbygget kodeeditor og en AI-underviser døgnet rundt. Den er en del af læringsforløbet i Kotlin Academy, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. Kotlin Academy-kurset indeholder 4 lektioner i alt.
Map-baserede egenskaber
Kotlin tillader, at du delegerer egenskaber direkte til en Map. Når du læser egenskaben, slås dens navn op i map'et.
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-delegering
For egenskaber, der kan ændres, skal du delegere til en MutableMap, så ændringer opdaterer det underliggende map.
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-deserialisering med Map-delegering
Analysér et JSON-lignende map, og eksponér dets felter som typede egenskaber ved hjælp af map-delegering — ideelt til dynamiske data.
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
}Mønsteret logningsdelegering
Pak enhver delegering ind i logning for gennemsigtigt at spore hver læsning og skrivning på tværs af alle delegerede egenskaber.
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" }Kombination af Map + logning
Lag en logningswrapper omkring map-delegering for at få et komplet revisionsspor over dynamisk adgang til egenskaber.
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-lignende delegering
En delegering, der gemmer værdier i et underliggende map, som simulerer SharedPreferences — tilpas den til rigtige Android-præferencer ved at udskifte map'et med kald til de faktiske præferencefunktioner.
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
}Typede præferencehjælpere
Opret typede hjælpefunktioner for hver primitiv præferencetype, så kaldestederne bliver mere overskuelige.
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}") }Delegering til revisionslog
Registrér hver ændring af en egenskab med et tidsstempel i en revisionsliste — ideelt i scenarier med krav om overholdelse af regler eller fejlfinding.
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)
}Validering + map-lagring
Kombinér map-lagring med validering: Afvis ugyldige værdier, før de skrives til map'et.
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) }
}Mønsteret delegeringssammensætning
Sammensæt flere delegeringsfunktioner ved hjælp af en API i builder-stil: Start med en grundlæggende delegering, og læg derefter logning, validering eller caching ovenpå.
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)
}
}
}Virkelighedsnært: Konfigurationsobjektmønsteret
Brug map-delegering til at opbygge et konfigurationsobjekt fra eksterne kilder som miljøvariabler eller en JSON-konfigurationsfil.
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}")
}Hurtigt tjek
Hvad sker der, når du delegerer en egenskab til en Map?
Opsummering
Delegeringer åbner for effektive mønstre: map-delegering til dynamiske data og JSON-data, vedvarende lagring i SharedPreferences-stil, revisionslogning til overholdelse af regler og sammensættelig validering — alt sammen uden at ændre kaldestederne.
Lær Kotlin med en AI-underviser — gratis
Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.
- Kurser
- 51
- Lektioner
- 203
Ofte stillede spørgsmål
Er lektionen “Delegates til indstillinger, map-baserede egenskaber og logning” gratis?
Ja — alle 3 lektioner i læringssporet Kotlin Academy, inklusive “Delegates til indstillinger, map-baserede egenskaber og logning”, kan læses gratis i deres fulde længde her på webstedet. Derefter låser CoddyKit PRO alle lektioner op samt interaktive øvelser med en indbygget kodeeditor og en AI-underviser døgnet rundt. Kotlin Academy-kurset indeholder 4 lektioner i alt.
Hvad lærer jeg i “Delegates til indstillinger, map-baserede egenskaber og logning”?
Anvend delegates til SharedPreferences, map-lagring og audit-logning. Du øver dig i Kotlin Academy med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.
Skal jeg have erfaring for at begynde på Kotlin Academy?
Der kræves ingen tidligere erfaring. Kotlin Academy på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 4 af 4.
Hvor lang tid tager lektionen “Delegates til indstillinger, map-baserede egenskaber og logning”?
De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.
Kan jeg skrive og køre kode i denne Kotlin Academy-lektion?
Ja. Alle Kotlin Academy-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.
Alle lektioner i dette kursus
- by lazy: Dybdegående gennemgang af udskudt initialisering
- observable- og vetoable-delegates
- Skriv en tilpasset ReadWriteProperty-delegate
- Delegates til indstillinger, map-baserede egenskaber og logning