0

I'm using Kotlin and thought about writing universal method to check if any of passed arguments are not null.

Method could be used in if statement instead manually checking each argument. And if parameters are not null then compiler should assume that inside if statement they are still not null. Example below:

fun getFoo(): Foo? {
  //return value
}

fun getBar(): Bar? {
  //return value
}

fun execute(foo: Foo, bar: Bar) {
  //do stuff
}

This is "traditional" way:

val foo = getFoo()
val bar = getBar()
if(foo != null && bar != null) {
  execute(foo, bar)
}

And this is what I thought to do:

fun isNotNull(vararg params: Any?): Boolean {
  return params.filterNotNull().isNotEmpty()
}

val foo = getFoo()
val bar = getBar()
if(isNotNull(foo, bar)) {
  execute(foo, bar)
}

Of course code above is not compiling (Type mismatch, Required: Foo, Found: Foo?).

Is there any way to assure compiler that foo and bar was already checked for null? I could use !! in each parameter but it's not very elegant solution. Maybe some construction using contract?

When using manual check foo != null && bar != null then there is not problem because of automatic smart cast to Foo and Bar.

user3626048
  • 706
  • 4
  • 19
  • 52

1 Answers1

1

I'm not entirely sure why you'd need a custom function for this. The idea behind kotlin null safety is to avoid the need for these methods. A simple case is using let:

fun m(foo: Foo?) {
  foo?.let {
      // it is not null here
  }
}

That said, should the need for such a method arise, there's a new experimental feature called contracts that enables smart casts. You could write a method like so (I haven't tried this myself, read more about it here

fun String?.isNullOrEmpty(): Boolean {
  contract {
    returns(false) implies (this@isNullOrEmpty != null)
  }
  return this == null || isEmpty()
}

This is for a string, but I guess one could do it for Any. I also think this specific method already exists in the stdlib anyway.

Again, it feels to me this is a bit pointless, but at least it's possible. You'll need to enable the experimental features.

Fred
  • 16,367
  • 6
  • 50
  • 65
  • the idea was to use this function in condition check where I have to pass multiple parameters to 3rd party library and all of them should be ```not null```. Doing it manually I have to write 2 or 3 line ```if``` statement where I check every parameter is ```!= null```. I know that I can use ```?.let``` but like I said there is multiple variables to check. I tried to write something using ```contract``` but I don't have any experience with it and I don't really know how to use it in my method. – user3626048 Sep 03 '19 at 08:35
  • 1
    What happens if the parameters are null? Will you crash the app with an exception? If so, then just use `!!`. No need to check if they are null. The operator `!!` will do that for you. Going a step further, why even allow null? Just declare your method as not accepting nulls. – Fred Sep 03 '19 at 08:49