简体   繁体   English

Kotlin懒惰的默认属性

[英]Kotlin lazy default property

In Kotlin, how do i define a var that has a lazy default value ? 在Kotlin中,如何定义具有惰性默认值的var

for example, a val would be something like this: 例如, val将是这样的:

val toolbarColor  by lazy {color(R.color.colorPrimary)}

What i want to do is, have a default value for some property ( toolbarColor ), and i can change that value for anything else. 我想要做的是,有一些属性的默认值( toolbarColor ),我可以更改其他任何值。 Is it possible? 可能吗?

EDIT: This does the partial trick. 编辑:这是部分技巧。

var toolbarColor = R.color.colorPrimary
    get() = color(field)
    set(value){
        field = value
    }

Is it possible to ease this by writing 是否可以通过写作来缓解这种情况

var toolbarColor = color(R.color.colorPrimary)
    set(value){
        field = value
    }

in a way that the default value is computed lazily? 以某种方式懒惰地计算默认值? At the moment it won't work because color() needs a Context that is only initialized later. 目前它不起作用,因为color()需要一个仅在以后初始化的Context

You can create your own delegate method: 您可以创建自己的委托方法:

private class ColorDelegate<T>(initializer: () -> T) : ReadWriteProperty<Any?, T> {

    private var initializer: (() -> T)? = initializer

    private var value: T? = null

    override fun getValue(thisRef: Any?, property: KProperty<*>): T {
        return value ?: initializer!!()
    }

    override fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
        this.value = value
    }
}

Declare in some delegate: 在一些代表中声明:

object DelegatesExt {
    fun <T> lazyColor(initializer: () -> T): ReadWriteProperty<Any?, T> = ColorDelegate(initializer)
}

And use as follow: 并使用如下:

var toolbarColor by DelegatesExt.lazyColor {
    // you can have access to your current context here.
    // return the default color to be used
    resources.getColor(R.color.your_color)
}

...

override fun onCreate(savedInstanceState: Bundle?) {
    // some fun code
    // toolbarColor at this point will be R.color.your_color
    // but you can set it a new value
    toolbarColor = resources.getColor(R.color.new_color)
    // now toolbarColor has the new value that you provide.
}

I think this could be a cleaner way to do, but I don't know yet (starting with kotlin few days ago). 我认为这可能是一种更清洁的方式,但我还不知道(几天前从kotlin开始)。 I will take a look and see if this could be done with less code. 我将看看是否可以用更少的代码完成。

You can store your property in a map to basically create a mutable lazy. 您可以将您的属性存储在地图中,以基本上创建一个可变的懒惰。 You need a mutable map (like a HashMap<K, V> ) with a default function to delegate to: 您需要一个可变映射(如HashMap<K, V> ),并使用默认函数委派给:

var toolbarColor by hashMapOf<String, Any?>()
        .withDefault { toolbarColor = R.color.colorPrimary; toolbarColor }

You'll also need to import some extension functions: import kotlin.properties.getValue and import kotlin.properties.setValue . 您还需要导入一些扩展函数: import kotlin.properties.getValueimport kotlin.properties.setValue

It would be nice if Kotlin provided something built-in and optimized for this (like a mutableLazy or something). 如果Kotlin为此提供内置和优化(如mutableLazy或其他东西),那将是很好的。 As such, I've created KT-10451 . 因此,我创造了KT-10451

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM