简体   繁体   中英

How to use Kotlin's `with` expression for nullable types

The code below will not compile because the variable myType can be null. Is there a way of executing a with block for nullable types in Kotlin?

    val myType: MyType? = null
    with(myType) {
        aMethodThatBelongsToMyType()
        anotherMemberMethod()            
    }

You can convert a nullable type to a non-nullable type with the suffix !! :

with(myType!!) {
    aMethodThatBelongsToMyType()
    anotherMemberMethod()            
}

If the value is indeed null, it will throw a NullPointerException , so this should generally be avoided.

A better way to do this is to make the execution of the code block dependent on the value being non-null by making a null-safe call and using the apply extension function instead of with :

myType?.apply {
    aMethodThatBelongsToMyType()
    anotherMemberMethod()            
}

Yet another option is to check if the value is non-null with an if statement. The compiler will insert a smart cast to a non-nullable type inside the if-block:

if (myType != null) {
    with(myType) {
        aMethodThatBelongsToMyType()
        anotherMemberMethod()            
    }
}

You could define your own with function that accepts nullables, then determines whether to actually run based on whether the object is null.

Like this:

fun <T, R> with(receiver: T?, block: T.() -> R): R? {
    return if(receiver == null) null else receiver.block()
}

Then you can call the code the way you wanted to in the example with no issues, and the result will equal null if what you pass in is null .

Or, if the code block should (and could) be run either way, even if myType is null , then you'd define it like this instead:

fun <T, R> with(receiver: T?, block: T?.() -> R): R {
    return receiver.block()
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM