Skip to content

Instantly share code, notes, and snippets.

@zsqw123
Last active October 4, 2021 13:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zsqw123/3b3ba256edcbe0857a4e8238c2f8100e to your computer and use it in GitHub Desktop.
Save zsqw123/3b3ba256edcbe0857a4e8238c2f8100e to your computer and use it in GitHub Desktop.
kotlin 扩展属性 set 方法无法使用 feild 处理办法
import kotlin.reflect.KProperty
/**
* this will be used:
* 1. before getValue return.
* 2. before setValue to change the value.
*/
typealias ValueIntercepter<ValType> = (originValue: ValType) -> ValType
fun <ValType : Any?> exVar(
defVal: ValType, getter: ValueIntercepter<ValType> = { it }, setter: ValueIntercepter<ValType> = { it },
) = ExtensionValueDelegates(defVal, getter, setter)
class ExtensionValueDelegates<ValType : Any?>(
val defVal: ValType, val getter: ValueIntercepter<ValType>, val setter: ValueIntercepter<ValType>,
) {
var field: Any? = INVALIDATE
companion object {
object INVALIDATE
}
}
inline operator fun <This : Any, reified ValType> ExtensionValueDelegates<ValType>.getValue(thisRef: This, property: KProperty<*>): ValType {
val realV: ValType =
if (field != ExtensionValueDelegates.Companion.INVALIDATE) field as ValType
else defVal
return getter(realV)
}
inline operator fun <This : Any, reified ValType> ExtensionValueDelegates<ValType>.setValue(thisRef: This, property: KProperty<*>, value: ValType) {
field = setter(value)
}
@zsqw123
Copy link
Author

zsqw123 commented Oct 4, 2021

example Code:

class Awa

var Awa.b by exVar("defVal")
var Awa.c by exVar(123, getter = { it + 1 })
var Awa.d by exVar(
    defVal = 999,
    getter = { it + 100 },
    setter = { it + 10 },
)

fun main() {
    val awa = Awa()
    println(awa.b)
    awa.b = "777"
    println(awa.b)
    println()

    val awa2 = Awa()
    println(awa2.c)
    awa2.c = 555
    println(awa2.c)
    println()

    val awa3 = Awa()
    println(awa3.d)
    awa3.d = 13
    println(awa3.d)
    println()

    println(awa.b)
    println(awa2.c)
    println(awa2.d)
}

@zsqw123
Copy link
Author

zsqw123 commented Oct 4, 2021

maybe sometimes we need null delegates, it's ok!

var Awa.e: String? by exVar(null)

fun main() {
    val awa = Awa()
    println(awa.e)
    awa.e = "sdjskd"
    println(awa.e)
    awa.e = null
    println(awa.e)
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment