Intereting Posts
Kotlin переопределяет забаву с подтипом Можно ли избежать повторения кода, когда объект должен вернуть измененную копию самого себя? Наследование класса с помощью основного конструктора Как получить родительский класс внутри анонимного класса в kotlin Проект не будет построен с Kotlin 1.1.3 В Котлине, почему Джексон в некоторых случаях отказывается от несанкционированного не аннотированного объекта, а не в других RxJava запускает часть плана в основной теме Котлин: Пропустите и используйте функцию параметров 2? Могу ли я сравнить, равны ли два числа с плавающей запятой в Котлине? Как обеспечить класс kotlin для конфигураций запуска eclipse? Запустить Java в Kotlin-конвертер из командной строки? Как создать карту из списка с помощью внутреннего списка с помощью Kotlin Аннотации Android с Kotlin Создать общий класс с массивом типа Comparable <T> в kotlin? что означает эта ошибка при преобразовании из java-кода с общим в kotlin, один запрет после T?

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]) } } ... 

Причина в том, что лямбда не нуждается в ее блоке в фигурных скобках.

Так что не пишите

 out -> { ... } 

просто пиши

 out -> ... 

guenther уже сказал вам, что не так с вашим кодом, но я думаю, что объяснение того, что произошло, отсутствует.

Рассмотрим следующее:

 val x = { println("y") } 

Будет ли он распечатывать y ? Нет, ламда никогда не вызывается. Вы должны вызвать x() .

Давайте посмотрим, что вы сделали:

 val x = { { println("y") } } x() 

Будет ли он распечатывать y? Нет, потому что вы не вызываете лямбду, которая печатает y .

Чтобы сделать все более понятным, давайте укажем типы явно.

 val x:() -> (() -> Unit) = { { println("y") } } 

Теперь мы видим, что первая лямбда, вызываемая x() возвращает лямбда, поэтому вам нужно будет вызвать x()() , чтобы вызвать возвращенную лямбду.

Поэтому, используя вторую пару, фигурные скобки не просто необязательны, но дают код совершенно новое значение.


Но это означает, что будет и другое решение вашей проблемы.

 PrintWriter(FileWriter(File("./lines2.txt"))).use { out -> { println(lines.size) lines.forEach { out.println(it.split(":")[0]) } }() // <-- add braces here to invoke the lambda } 

Таким образом, вы можете либо удалить два скобки, добавить еще два. Твой выбор.

Отказ от ответственности: удалить две фигурные скобки – это путь. Другой вариант – просто доказать точку.