Proper usage of nullable vars after check for nullness

When I have the following code:

class MyClass {

  var myvar : String? = null


  fun setMyVar(value: String) {
  myvar = value;
  }


  fun someFunc() {
  if(myvar != null) {
          otherFunc(myvar) // <– gives an error, cannot pass String? to function which expects String
  }

  }
}


fun otherFunc(str: String) { /* do something with str */ }

So I wonder what is the idiomatic thing to do at the highlighted point?
Is it
otherFunc(myvar as String)
or
otherFunc(myvar!!)

I kinda expected Kotlin to figure out that I just did a null check, but it seems that it does this only for vals, not vars (I bet because vars are subject to concurrency issues).

We will make the compiler a little smarter with vars, although mostly with local vars: class properties may turn out to be computed and give another value each time. For now you should use !!

Got it, thanks!

Enjoying Kotlin very much so far!

Coming from Java it is also not very clear for my what are the best practices to structure packages.
If I got it right, Kotlin does not require 1to1 correspondence between dir structure and package names…

And in Java I used to write helper static methods and put them in namespace aka

ThemeParser.parse(filename)

in Kotlin I could just do

ThemeParser.kt:
fun parse(filename)

But then in some other file I could just write ‘parse(filename)’ after importing this function.

What bothers me a little is that this nice prefix is lost and ‘parse’ call looks just like a local one.

ThemeParser.parse() would have been much clearer to me.

isn't it better to use let instead?

 
myvar?.let {
    otherFunc(it)
}

From a point of view of clean OO programming you would go with ThemeParser().parse(filename) You could define a convenience class method ThemeParser.parse(filename), which calls the instance method parse(filename). But that doesn't buy you much since class instantiation is that concise in Kotlin.

As what

ThemeParser.kt:
fun parse(filename)

is concerned I would recommend only to do this when you have a good reason not to create an instance method (aka a method defined inside a class). I have problems to find a situation where this makes sense. Actually, I don’t understand why this kind of global methods can be defined in Kotlin. If you want a method to have “global scope” you could easily add it to class Object as an extension method or import it through a trait. Now people come and ask exactly that kind of question as in this thread. But I might be too narrow-minded here, being biased from the old days when developing in Smalltalk ;-).

Peace, Oliver

Hello, Oliver.

I am looking not from OO perspective, but from a functional one :slight_smile:

Why create a class when I do not need one. Just for the sake of wrapping some method which is static in its nature?
Seems not right. So I’m glad that Kotlin is that concise - it allows me to just create funcitons when I do not need classes.

I like this. I just didn’t get how to structure packages yet…

It's different behavior, and the choice is up to you

In ye olden days before Java insisted everything had to be in a class, we'd just call the function parseTheme() and be done with it :)

Yes, I am also starting to think that I just got this new java-land habit which is now hard to shake off :)

I think it is a better approach to have a static method Math.abs() as in Java rather than a global function abs(). Putting mathematical methods into a class Math still creates some order where you know where to look for things. Having an ever growing number of global functions results in a big soup where you have to know tons of things by heart. In Java you know that you have to look into class Math when looking for a mathematical function. Static imports in Java solve the problem of not having to type in Math.abs() all the time.

You still can use Java's Math class if targeting JVM. In "pure" Kotlin you could have 'math' package with all top level functions you need.

The point we are discussing here is that having the call looking like MyMath.abs() introduces some semantic context: by just looking at this call I can say that it comes from other source file (or module). On the other hand, if I just 'import mykotlinmodule.mymath' and then have 'abs()' in code - this doesn't immediately tell the reader of the code whether this 'abs()' call is defined in current source file or not.

I agree that having MyMath.abs() is better for readability.
This could be solved by qualified imports (aka Haskell/Python etc) but IIRC Kotlin doesn’t have any

You could always define the functions as part of an object to get those same semantics.

Yes, but that looks more like a workaround. I would have to instantiate that object for no reason. Altough this might be some minor detail not worth discussion, I don't know.

I think for something like "abs" it's pretty clear what it does without any prefix. For other more complicated functions, a longer name is probably as good as a prefix.

I sometimes do this, it results in one superflous line, but I like it.

var text: String? = null


fun printText() {
  val t = text
  if (t != null) {
           … (t is now smart cast as non-null String)
     }   
}

Nice trick, thank you.