0

I have this function

fun <T> safe(t: T?): T {
    return Optional.ofNullable(t).orElseThrow { IllegalStateException("safe value should not be null") }
}

I use it to say I know that T is not null now so give me back the non null-able form of it.

So I use it like this, I declare

class SomeType(val someOtherType: SomeOtherType?)

But some someOtherType in another place is declared like so:

class SomeThirdType(val someOtherType: SomeOtherType)

So in SomeType I have this function:

class SomeType(val someOtherType: SomeOtherType?) {
  fun doSomeDamage(): SomeThirdType {
    //some work
    return SomeThirdType(safe(someOtherType))
  }
}

I'm not happy with the safe function, is there a better way? I feel like I'm missing something fundamental here

jakstack
  • 2,143
  • 3
  • 20
  • 37
  • 1
    Does this answer your question? [What is the Kotlin double-bang (!!) operator?](https://stackoverflow.com/questions/34342413/what-is-the-kotlin-double-bang-operator) – IlyaMuravjov Apr 18 '20 at 15:16
  • Yes it does. But in my team we have a policy of not using !! is another way? – jakstack Apr 18 '20 at 15:31
  • I think your `safe` is pretty equivalent to `!!` (except slower and producing slightly less useful exception message) and all reasons not to use it would apply. – Alexey Romanov Apr 18 '20 at 18:00

2 Answers2

2

Kotlin already gives you tools to work with nullable types. I would just use scope functions and/or elvis operator. In your specific case, elvis operator seems enough.

class SomeType(val someOtherType: SomeOtherType?) {
  fun doSomeDamage(): SomeThirdType {
    //some work
    return SomeThirdType(someOtherType ?: error("someOtherType should not be null"))
  }
}
Diego Marin Santos
  • 1,923
  • 2
  • 15
  • 29
  • Thanks, Yes that would work too but using safe function is neater and less noise in my view – jakstack Apr 18 '20 at 16:00
  • “Kotlin already gives you tools”.  Indeed!  Nulls are a lot less scary in Kotlin, because you always know when they're possible, and the compiler won't let you do anything unsafe.  And the safe-call operator, the elvis operator, and a host of extension functions with nullable receivers make it much more pleasant to deal with nulls when they _can_ occur.  Don't be afraid of them! – gidds Apr 18 '20 at 23:08
0

A "user" of the SomeType class would not expect a crash upon a simple doSomeDamage() function call. The SomeType is fully constructed and yet doSomeDamage will likely crash.
I personally prefer :

fun doSomeDamage(someOtherType: SomeOtherType): SomeThirdType // with no-arg constructor

or if SomeOtherType really does belong to SomeType (which I feel not):

fun doSomeDamage(): SomeThirdType? = someOtherType?.let{...}