Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Lazy class delegate in Kotlin?

I'm trying to do a Facade of my interfaces to abstract real types and omit need to name all of them directly. I ended up with this:

class Facade : ILeft by LeftImpl(), IRight by RightImpl()

ILeft and IRight are interfaces and I instantiate their implementations. This is in general solution I was looking for and it worked.

BUT

Let's say, I know, I will use most of the time only ILeft, or IRight. There are cases where I use them both, but most of the time, I'll use just one. Thus I would like to make them lazy, but how?

1) It's possible to use instance provided in the constructor, but that requires an instance.

2) If I try to define:

class Facade : ILeft by left, IRight by right {
     val left by lazy { LeftImpl() }
     val right by lazy { RightImpl() }
}

The left and right are inaccessible in the class declaration.

I can make the implementations lazy inside, that's also a possibility. But I'm trying to find a way, to write this out of the box, just by kotlin.

Any ideas how to have Facade object with just ILeft actually initialized by implementation?

like image 713
l0v3 Avatar asked Aug 16 '18 12:08

l0v3


People also ask

What is lazy delegate Kotlin?

Lazy properties lazy() is a function that takes a lambda and returns an instance of Lazy<T> , which can serve as a delegate for implementing a lazy property. The first call to get() executes the lambda passed to lazy() and remembers the result. Subsequent calls to get() simply return the remembered result.

How do you use lazy in Kotlin example?

Example. In this example, we will declare a lazy variable "myName" and we could see that the call to this parts of the code will happen only once and when the value is initialized, it will remember the value throughout the application. Once the value is assigned using lazy initialization, it cannot be reassigned .

What is a delegate Kotlin?

Delegation (in computer science) is the assignment of authority from one instance to another. It can operate mutable as well as static relationship between classes, and inheritance, in turn, is based on the constant concept.

How does Kotlin lazy work?

Simply, lazy creates an instance that performs initialization at the first access to the property value, stores the result, and returns the stored value.


1 Answers

Kotlin does not currently support implementing interfaces by delegating them to properties (KT-83), only constructor parameters can be used in expressions used in delegation, and these expressions are always evaluated at construction time.

So, indeed, you will likely need to define lazy proxy implementations for the interfaces:

class ILeftLazy(lazyLeft: Lazy<ILeft>): ILeft {
    private val left by lazyLeft

    override fun someLeftFun(): Foo = left.someLeftFun()
    /* ... */
}

Then you can rewrite the Facade primary constructor to accept Lazy instances and implement the interfaces by delegation to the implementations:

class Facade(
    lazyLeft: Lazy<ILeft>
    lazyRight: Lazy<IRight>
) : ILeft by ILeftLazy(lazyLeft), IRight by IRightLazy(lazyRight) {
    val left by lazyLeft
    val right by lazyRight
}

You can then make the primary constructor private and provide a no-arg secondary constructor that passes lazy { ILeftImpl() } and lazy { IRightImpl() } to the primary one.

This requires some boilerplate implementing the lazy proxy implementations but still allows you to implement the interfaces in Facade by delegation.

like image 121
hotkey Avatar answered Sep 30 '22 14:09

hotkey