Kotlin continuing to else clause after return
Kotlin continuing to else clause after return
I am trying to figure out how returns work in Kotlin. Right now I have a function that with two nested for loops.
All returns should return for the parent function getValue(), one seems to work as expected, the other one does does not.
val myArray = arrayOf(
MyObj("String 1", mapOf(Pair(MyEnum.apple, "String 2"))),
MyObj("String 2", mapOf(Pair(MyEnum.orange, "String 1"),
Pair(MyEnum.apple, "String 3"))),
MyObj("String 3", mapOf(Pair(MyEnum.orange, "String 2")))
)
val myObj = myArray[1]
fun main(args: Array<String>) {
getValue(MyEnum.apple)
}
fun getValue(myEnum: MyEnum) {
myObj.myMap.forEach { (enum, str) ->
if (enum == myEnum) {
myArray.forEach {obj ->
if (obj.name == str) {
if (checkStuff(obj)) {
println("checkStuff returned true")
return // this continues to printLn
}
println("returned false")
return // This appears to return as expected
}
}
} else {
println("Should not be hit")
}
}
}
fun checkStuff(obj: MyObj): Boolean {
return obj.name == "String 1"
}
data class MyObj (val name: String, val myMap: Map<MyEnum, String>)
enum class MyEnum {
apple, orange, pear
}
The return inside the checkStuff if always continues onto the printLn.
From reading through documentation, I thought that adding return@getValue would return for the top level function and exit out of that function.
I seem to be missing something. How would I make the first return not continue on to the else clause with the printLn?
I have edited my question to include some code that will compile and reproduce the behavior I am getting. Thanks.
– Josh G
Jul 1 at 4:51
All these
return statements will return from the entire getValue function when they are hit. As for "The return inside the checkStuff if always continues onto the println.", this happens because checkStuff is only called once with the third element of your array, and it evaluates to false on that element. This is not a language but a logic issue, I suggest stepping through your code with the debugger and seeing what values your various if checks operate on.– zsmb13
Jul 1 at 5:17
return
getValue
checkStuff
false
if
2 Answers
2
You need to fix your if-statements logic,
at current state checkStuff can't return true
checkStuff
true
fun getValue(myEnum: MyEnum) {
myObj.myMap.forEach { (enum, str) ->
if (enum == myEnum) { // Pair(MyEnum.APPLE, "String 3")
myArray.forEach { obj -> // str = "String 3"
if (obj.name == str) { // obj.name = "String 3"
if (checkStuff(obj)) { // "String 3" == "String 1"
// checkStuff: obj.name == "String 1"
...
}
...
The return statements work fine. The problem with your code is that the only time checkStuff(obj) gets called it returns false, therefore the following is never called:
checkStuff(obj)
`println("checkStuff returned true")
return // this continues to printLn`
If you make the appropriate changes to fun checkStuff(..) {...} you will find that the code works just like you expected.
fun checkStuff(..) {...}
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
The code wouldn't compile. To discuss about how and why some code bahaves the wy it does, we need something that actually compiles and runs. Post a complete minimal example that compiles, runs, and reproduces your issue.
– JB Nizet
Jun 30 at 23:27