Search code examples
kotlinkotlin-null-safety

Set a value to builder if not null - Kotlin


I am new to Kotlin. Can someone tell me how can I set the value only if not null here in below cade. There should be a way to use with let() but I am not sure how to do it.

If the var2 is not null only I should set it. Otherwise null pointer error will throw.

private fun myFunc(var1: Type1 , var2: Type2?) {
    
        val request = class1.newBuilder()
            .setType1(var1)
            .setType2(var2) // how to set var2 only if not null? 
            .build()
        clientClass.send(request)
 }

Solution

  • If each builder function returns a new Builder instance, use run:

    private fun myFunc(var1: Type1 , var2: Type2?) {
        val request = class1.newBuilder()
            .setType1(var1)
            .run { if(var2 != null) setType2(var2) else this }
            .build()
        clientClass.send(request)
    }
    

    If the builder functions mutate and return the same Builder instance, it’s simpler to use apply

    private fun myFunc(var1: Type1 , var2: Type2?) {
        val request = class1.newBuilder()
            .setType1(var1)
            .apply { if(var2 != null) setType2(var2) }
            .build()
        clientClass.send(request)
    }
    
    // or more cleanly using apply for everything instead of chaining:
    
    private fun myFunc(var1: Type1 , var2: Type2?) {
        val request = class1.newBuilder().apply {
            setType1(var1)
            if(var2 != null) setType2(var2)
            build()
        }
        clientClass.send(request)
    }
    

    Example of a Builder class whose functions return new instances:

    fun setType2(type2: Type2): Builder {
        return CombinedBuilder(this, type2) // a new object
    }
    

    Example of a Builder class whose functions return the same instance:

    fun setType2(type2: Type2): Builder {
        this.type2 = type2
        return this // the same object
    }
    

    The second type is more common, but sometimes the first type is used. You might have to check the source code to know for sure. If you can't be sure, use the .run method because it will work for either.