This question already has answers here:
In Kotlin, what is the idiomatic way to deal with nullable values, referencing or converting them
(4 answers)
Closed 4 years ago.
I sometimes see statements like somevariable.value?.add() What purpose does the question mark serve?
(Sorry, at the time of post I had no idea this was Kotlin, I thought it was java)
Kotlin treats null as something more than the source of null-pointer exceptions.
In your code snippet, somevariable.value is of a "nullable type", such as MutableList? or Axolotl?. A MutableList cannot be null, but a MutableList? might be null.
Normally, to call a function on an object, you use a ..
One option for calling a function on a variable, parameter, or property that is
of a nullable type is to use ?.. Then, one of two things will happen:
If the value is null, your function call is ignored, and null is the
result
If the value is not null, your function call is made as normal
So, in your case:
If somevariable.value is null, the add() call is skipped
If somevariable.value is not null, the add() call is made on whatever somevariable.value is
Related
This question already has answers here:
What's the difference between !! and ? in Kotlin?
(6 answers)
Closed 6 months ago.
I've read that using "!!" Instead of "?." In kotlin is not recommended. What is the difference between the 2 when checking for null in variables?
!! - is a developer's way of telling the compiler, trust me, I know this value will not be null. It is an unsafe way of converting a nullable value to a non nullable type. Unsafe meaning that it can throw a NullPointerException if the value is indeed null.
You can read more about it here.
?. - is a developer's way of telling the compiler that in the case where the value is not null, do the rest of the logic followed after the ?. sign. This way is the safe way to access a nullable type.
You can read more about it here
"?." and "!!" are not the same.
"?." operator also called safe call operator which is used to safely access properties from a nullable object
Refer to this link
Whereas "!!" is called a not-null assertion operator, it forcefully denotes a nullable type as not null. using this operator without any check for null will lead to NullPointerException.
Refer to this link
No both are different.
!! operator is called as double bang operator in kotlin. It means you are forcefully nullable fields as non nullable. It will throw NullPointerException when the particular nullable field is null.
var s :String? = null
var b :String = s!!.lowerCase() // It will throw null pointer exception as you are asserting nullable variable as non null
?. is null safe call operator. It is used for making null safe access to particular field.
var s :String? = null
var b :String? = s?.lowerCase() //Here lowerCase will not execute because you are making safe call only if value is not null.
var s :String? = null
var b :String = b?.lowerCase() ?: ""
Additional thing if you need to b as non null during safecall operator you can use ?: (elvis) operator to have default value if previous safe call statement is null.
This question already has answers here:
Why does (int)(object)10m throw "Specified cast is not valid" exception?
(4 answers)
Closed 2 years ago.
Okay, so I'm no stranger to coding and this strikes me as absolutely silly. Maybe someone can shed some light on why this is failing as usually VB.Net is intuitive and flexible with this type (pun intended) of thing?
I have a simple example, where I want to pass an object set with an integer value of lets say 6 to a procedure with a nullable Int64 parameter. I'd like to do so as I can't change the incoming value from object, it is a property of a class and may very well be nothing, hence the nullable Int64 being used.
Private Sub NullableParamTest(ByVal ID As Int64?)
MsgBox(ID)
End Sub
Now a simple sample like this will cause the exception:
Dim objTest As Object = 6
NullableParamTest(objTest)
Why is this not being boxed properly when the object is being set to an integer and passing to a procedure with an Int64? type? If I wrap the objTest with CInt(objTest) and cast it first it's fine, but I shouldn't need to do that at least in VB. I have logging methods that optionally take in various IDs as Int64? but the source is this Object property causing it to fail...even though they have perfectly valid Int64s set.
I wanted to avoid the whole Optional...Int64 = Nothing as that's not really setting it to nothing, granted it works as my IDs would never be zero but it's not true to what is really going on.
Thanks to the comments from #GSerg, it appears the following is the answer to this question found here:
A boxed value can only be unboxed to a variable of the exact same type.
It links to another answer describing this behavior as being performance related. In short you have to convert/cast the value within the object first before passing it.
In my case my passed value of an ID would never be 0 so using a regular Int64 and checking that it's nothing would work, otherwise using Object for a type is the alternative as wrapping all of the method calls with over half a dozen converts would be hideous.
The other comment by #GSerg mentions the notation of adding an & after the value to make it an explicit Int64, also allowing it to work in this case. Note that casting the value in this way as an Int32, which in theory would work (as it fits within an Int64 space), in fact does not due to the first part of my comment that it has to be unboxed as the exact same value type for the parameter.
This question already has answers here:
Single exclamation mark in Kotlin
(7 answers)
Example of when should we use run, let, apply, also and with on Kotlin
(6 answers)
Closed 2 years ago.
In the code below. I found in Intellij Idea compiler that val a and val b by default are "val a: StringBuilder" & "val b: StringBuilder!"
what is the difference between the two? What's the difference between StringBuilder and StringBuilder! ? Thank you :)
fun main(){
val a = StringBuilder().apply { // by default is val a : StringBuilder
append("Hello ")
append("from me")
}
println(a)
val b = StringBuilder().run { // by default is val b : StringBuilder!
append("Hello ")
append("from me")
}
println(b)
}
The ! indicates a platform type. It means that the compiler can't tell whether the type is nullable or not, because it comes from Java (or another JVM language), which doesn't make the distinction between nullable and non-nullable types, and doesn't have an annotation (#Nullable or #NonNull) to indicate that.
As a result, the compiler won't be able to make its usual null checks, so you should take care.
If you know (from the documentation, or looking at the Java code, or whatever) whether the value could be null or not, it's a good idea to specify the type explicitly (as either nullable with a trailing ?, or non-nullable without).
In this case, the difference is that apply() returns the value it was called on; that's all Kotlin, so the compiler knows its type. However, run() returns the last value in the lambda, which is the result of the last append() call. That method is defined in Java (since StringBuilder is part of the Java standard library), so the compiler can't tell whether it's nullable or not. But it's clear from the documentation that the method simply returns the StringBuilder it was called on, and so cannot be null. So for safety, you could specify an explicit StringBuilder type (i.e. non-nullable) for b.
This question already has answers here:
In Kotlin, what is the idiomatic way to deal with nullable values, referencing or converting them
(4 answers)
Closed 4 years ago.
I do not know what's use of nullable in some case in Kotlin. Let me hold an example.
There is a method.
fun hello(name: String)
As you see, the param name is non null. Then I will use it.
hello(bob!!) // bob is a nullable string
If bob is null, above code will throw KotlinNullPointerException. So I have to wrap check.
if(bob != null) {
hello(bob!!)
}
So in this situation, what's the best practice? And what's use of nullable?
It is a matter of you code business logic to decide.
Usually you will want to use the '!!' operator in case you are 100% sure that bob is not null. In that case '!!' is a clean non-verbose way to ignore the option that 'bob' is null.
If there is a chance that bob is null, use if/else or in case that it is a business error it is advisable to throw an appropriate business exception or handle it in the usual way you are handling errors in your project.
This is how you would use such a function:
fun hello(bob: String) {
println(bob);
}
hello("Bob!!");
What this means is that the function hello has a parameter named bob, with a datatype of String.
In your example, you are giving the hello function a variable that has not been declared (bob), and as such the JVM cannot pass along anything but null. If you want to pass in a variable named bobby, the code would look like this:
fun hello(bob: String) {
println(bob);
}
val bobby = "Hello!!!";
hello(bobby);
Hope this helps in your endeavors :)
What's use of nullable?
Take for example a boolean variable which can only hold 2 types of values, true of false. There is no way to signify "undefined". Sometimes we need a way to tell that variable is in an undefined state. For eg, in database or network interaction, you may not receive any value so then variable has to exist in some undefined state and that's what null value signifies.
This not just applies to Kotlin, it applies to any language.
what's the best practice?
With nullable types, there is always a risk of null pointer exception, so better check for null before accessing it, and in here
if(bob != null) {
hello(bob!!)
}
no need to do bob!!, just bob will do, since you have done a null check, Compiler keeps track of the null check and will let you use that variable.
Use non-null assertion (!!) when you are absolutely sure the variable is not null and in that case, no need to surround with null check as well.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Method overloading in Objective-C?
Is method overloading not possible.
I have two functions with the same name.
When declared like the below i'm etting errors.
-(RS232Msg*)CreateMessage:(REMOTE_MESSAGE_ID) nMessageNumber;
-(RS232Msg*)CreateMessage:(const uint8_t*) szMessageName;
when declared -(RS232Msg*)CreateMessage:(const uint8_t*) szMessageName; i'm not getting any errors.
I also have two functions as the same name with different return type and argument.But its working fine and there is no error in its declaration.
Why is it so?
No, method overloading is not possible in C, and therefore not possible in Objective-C (since Objective-C is a superset of C). If you'd like to use those two methods, you'll have to change their names. I would suggest the following:
- (RS232Msg *)createMessageWithMessageID:(REMOTE_MESSAGE_ID)nMessageNumber;
- (RS232Msg *)createMessageWithName:(const uint8_t*)szMessageName;