https://kotlinlang.org logo
Title
f

farmerbb

12/05/2019, 8:19 PM
If I have two `var`s with the exact same implementation in their setter functions, is it possible to extract that logic out into a single function then assign it as the setter?
r

Ruckus

12/05/2019, 8:20 PM
Depends on the logic, but if it has a backing field, it will require at least some rewrite.
f

farmerbb

12/05/2019, 8:21 PM
Yeah, I’m wanting it to include a backing field.
r

Ruckus

12/05/2019, 8:23 PM
Depending on what you're trying to do, probably not, as there's no way that function could know which backing field you're talking about. If you restructure the of the new function to take in the current value and return the new you could.
👍 1
Something like this maybe?
class Test {
    var a = "a"
        set(value) {
            field = checkValue(field, value)
        }
    var b = "b"
        set(value) {
            field = checkValue(field, value)
        }

    private fun checkValue(current: String, new: String): String {
        return if (new > current) new else current
    }
}
f

farmerbb

12/05/2019, 8:27 PM
That makes sense. I was kinda hoping for something along the lines of
set(value) = checkValue(field, value)
but this seems clean enough. Thanks
r

Ruckus

12/05/2019, 8:28 PM
Yeah, unfortunately the setter has to return
Unit
, so that won't work.
👍 1
s

streetsofboston

12/05/2019, 8:30 PM
What about writing a property delegate?
3
class GreatestDelegate<T: Comparable<T>>(initialValue: T) {
    private var backingField: T = initialValue

    operator fun getValue(host: Any?, property: KProperty<*>): T  {
        return backingField
    }

    operator fun setValue(host: Any?, property: KProperty<*>, value: T) {
        if (value > backingField) {
            backingField = value
        }
    }
}

class Test {
    var a: String by GreatestDelegate("")
    var b: String by GreatestDelegate("_")
}
👍 2
r

Ruckus

12/05/2019, 8:42 PM
That is a far better idea. I'm ashamed it didn't even cross my mind.
f

farmerbb

12/05/2019, 8:42 PM
Excellent, this is more or less the idea I was looking for. Appreciate it!