Kotlin Lambda不在内部调用代码
我遇到了最奇怪的事情。
比方说,我有一个名为“lines.txt”的文本文件。 该文件包含键值对中的行。
test:100 test1:200 test2:300 test3:400
如果我在Kotlin中读取这个文件,列表不是空的,但是输出流中的循环没有被调用。
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]) } } } } }
我不明白为什么这是如果任何人都可以启发我,这将是真棒。
该列表不是空的。 一个println(lines.size)
会显示给你,因为println
永远不会被调用。
你只是有一对花括号太多。
改变你的代码
... PrintWriter(FileWriter(File("./lines2.txt"))).use { out -> // list is empty?? println(lines.size) lines.forEach { out.println(it.split(":")[0]) } } ...
原因是,一个lambda不需要在大括号中的块。
所以不要写
out -> { ... }
只写
out -> ...
guenther已经告诉过你的代码有什么问题,但是我认为对发生的事情的一个解释不见了。
考虑以下几点:
val x = { println("y") }
它会打印出来吗? 不,lamda从不被调用。 你必须调用x()
。
让我们来看看你做了什么:
val x = { { println("y") } } x()
它会打印出来吗? 不,因为你不调用打印y的lambda。
为了使事情更清楚,让我们明确地指定类型。
val x:() -> (() -> Unit) = { { println("y") } }
现在我们可以看到,由x()
调用的第一个lambda也返回一个lambda,所以你将不得不调用x()()
来调用返回的lambda。
所以使用第二对花括号不仅是不可选的,而是给代码一个全新的含义。
但是这意味着你的问题还会有另一个解决方案。
PrintWriter(FileWriter(File("./lines2.txt"))).use { out -> { println(lines.size) lines.forEach { out.println(it.split(":")[0]) } }() // <-- add braces here to invoke the lambda }
所以,你可以删除两个括号,再加两个。 选择是你的。
免责声明:删除两个大括号是要走的路。 另一种选择只是为了证明一个观点。