0

I have a default function like this:

fun <T> makeDefault(): Animal<T> = Animal<Nothing>(
    name = "",
    size = 0,
    age = 0
)

I saw that there is the by operator, which can be used for view models like this:

val model: MyViewModel by viewModels() 

Question: How I can create a function that behaves like that for my makeDefault()?

What I want to do:

val animal: Animal<Dog> by makeDefault()
J_Strauton
  • 2,270
  • 3
  • 28
  • 70

1 Answers1

2

You can create your own Delegate, not extension:

import kotlin.reflect.KProperty

class DefaultDelegate<T> {
    private var created: Animal<T> = Animal<Nothing>(
            name = "",
            size = 0,
            age = 0
        )

    operator fun getValue(thisRef: Any?, property: KProperty<*>): Animal<T> {
        return created
    }

    operator fun setValue(thisRef: Any?, property: KProperty<*>, value: Animal<T>) {
        created = value
    }
}

Then use it:

val animal: Animal<Dog> by DefaultDelegate()

For more information, see Delegated properties doc

S-Sh
  • 3,564
  • 3
  • 15
  • 19
  • It should be noted that since all this is doing is returning a constant instance, a delegate is just introducing extra overhead for no benefit. – Tenfour04 Apr 03 '20 at 16:11
  • Thank you for the great answer and thank you @Tenfour04 for the useful comment – J_Strauton Apr 03 '20 at 16:30