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 } 

所以,你可以删除两个括号,再加两个。 选择是你的。

免责声明:删除两个大括号是要走的路。 另一种选择只是为了证明一个观点。