
That is not to say everything about this solution is bad. You could argue that you just need an elvis check on the end but you are opening yourself up to side effects explained in my other post. We are now hiding a potential issue that we would want to know about (that textViewState is null) and instead showing the user an unexpected state. If we aren’t expecting textViewState to be null, then we could have some unexpected defaults and our view might show up inappropriately in the layout or have some demo text that we expected to be removed. The possible side effect would be that is unknown what are the default values of that textView. This code would safely run whether or not our textViewState is null but a lot of developers could end up in a weird side effect. The safe unwrap is probably the solution most developers would usually go to but could lead to some trouble. We know that it will never throw (or if it does, it’s an error we should know about) and because of the contract we are safe to use myInput as a non-null variable. To use the example from before, you can simply add that line before the length variable declaration. Since it is written using contracts, you don’t even need to use the return value. RequireNotNull is a function is kotlin’s standard library that throws an IllegalArgumentException if the value is null otherwise returns the not-null value. You also get the added benefit that the compiler will smartcast to a non-nullable type so you can use it safely later in your code. By switching to the throw, you can write out a better explanation of what happened and include any debugging information to send to your crash logger. Doing a not-null assertion would result in a KotlinNullPointerException with no information about what is null other then the line it occurred on. The benefit of this solution is it allows you to better define an error message which could help track things down better.

The elvis operator with a throw ends up looking something like this: val nonNullValue = arguments?.getString("KEY") ?: throw IllegalStateException("Unable to find string KEY in arguments") It should be used carefully but as long as the developer could argue why this would never throw, it does not make sense to create a rule against using this. Since, as a user, we can be confident that variable is never null it would make sense here to use the not-null assertion operation for myInput!!.length. Also, the developer may not own the function so that would not provide a good solution. This is where someone would bring up contracts, but this feature is still experimental which some code bases will not allow. Since myInput is a nullable type, even though we check in the isInputValid function and assert that myInput is not null, the compiler cannot confidently state that myInput is no longer null in the scope of that if statement and will not compile.
