Reputation: 13
I encountered the strangest thing.
Lets say I have a text file called "lines.txt". This file contains lines in key value pairs.
test:100
test1:200
test2:300
test3:400
If I read this file in Kotlin the list is not empty however the loop inside the output stream does not get called.
object App {
@JvmStatic
fun main(args: Array<String>) {
// file containing lines of text
val lines = Files.readAllLines(Paths.get("./hashes.txt"))
// not empty
println(lines.size)
// write back a modified version
PrintWriter(FileWriter(File("./lines2.txt"))).use { out -> {
// this doesn't get called
println(lines.size)
lines.forEach {
out.println(it.split(":")[0])
}
}
}
}
}
I don't understand why this is so if anyone can enlighten me that would be awesome.
Upvotes: 1
Views: 834
Reputation: 29844
guenther already told you what is wrong with your code, but I think an explanation of what happened is missing.
Consider the following:
val x = { println("y") }
Will it print out y? No, the lamda is never invoked. You have to call x()
.
Let's take a look at what you did:
val x = { { println("y") } }
x()
Will it print out y? No, because you don't invoke the lambda that prints y.
To make things more clear, let's specify the types explicitely.
val x:() -> (() -> Unit) = { { println("y") } }
Now we can see that the first lambda invoked by x()
returns a lambda as well so you would have to call x()()
in order to invoke the returned lambda as well.
So using a second pair a curly braces is not just not optional but gives the code a whole new meaning.
But this means that there would be also another solution to your problem.
PrintWriter(FileWriter(File("./lines2.txt"))).use { out -> {
println(lines.size)
lines.forEach {
out.println(it.split(":")[0])
}
}() // <-- add braces here to invoke the lambda
}
So, you can either remove two brackets are add two more. Choice is yours.
Disclaimer: Removing two braces is the way to go. The other option is just to prove a point.
Upvotes: 2
Reputation: 12167
The list is not empty. A single println(lines.size)
will shown you that, because that println
is never called.
You simply have one pair of curly braces too much.
change your code to
...
PrintWriter(FileWriter(File("./lines2.txt"))).use { out ->
// list is empty??
println(lines.size)
lines.forEach {
out.println(it.split(":")[0])
}
}
...
The reason is, that a lambda doesn't need its block in curly braces.
So don't write
out -> { ... }
just write
out -> ...
Upvotes: 2