Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I lazy init a value depending on constructor?

Tags:

kotlin

I have a class where I either know a specific value on creation, or I need to generate it, which is somewhat expensive. Can I generate the value only when it's actually needed?

val expensiveProperty: A
constructor(expensiveProperty: A) {
    this.expensiveProperty = expensiveProperty
}
constructor(value: B) {
    // this doesn't work
    this.expensiveProperty = lazy { calculateExpensiveProperty(value) }
}
like image 441
Chris Avatar asked May 25 '17 05:05

Chris


People also ask

Which one is true about lazy initialization of objects?

Lazy initialization of an object means that its creation is deferred until it is first used. (For this topic, the terms lazy initialization and lazy instantiation are synonymous.) Lazy initialization is primarily used to improve performance, avoid wasteful computation, and reduce program memory requirements.

What is the difference between Lateinit and lazy?

Lazy initialization is one of the property Delegate-s, while late initialization requires the use of a language keyword. Lazy initialization applies only to val, and late initialization applies only to var fields. We can have a lazy field of a primitive type, but lateinit applies only to reference types.

Is lazy initialization good?

Lazy initialization is useful when calculating the value of the field is time consuming and you don't want to do it until you actually need the value. So it's often useful in situations where the field isn't needed in many contexts or we want to get the object initialized quickly and prefer any delay to be later on.

How would you accomplish lazy initialization in net?

Net Framework 4.0 to provide a thread-safe way to implement lazy initialization. You can take advantage of this class to defer the initialization of resource-intensive objects in your application. When you use the Lazy<T> class, you need to specify the type of object you intend to create lazily in the type argument.


1 Answers

It's possible, but with a twist:

class C private constructor(lazy: Lazy<A>) {
    val expensiveProperty by lazy

    constructor(value: B) : this(lazy { calculateExpensiveProperty(value) })
    constructor(expensiveProperty: A) : this(lazyOf(expensiveProperty))
}

Note how I kept primary constructor private while leaving secondary constructors public.

like image 73
glee8e Avatar answered Oct 21 '22 14:10

glee8e