#kotlin
#kotlin
Вопрос:
В Scala вы можете написать
val x = {
... do some complex computations ..
42
}
чтобы скрыть материал внутри блока кода.
Самое близкое, что я нашел в Kotlin, это:
val x = {
... do some complex computations ..
42
}()
Есть ли лучший способ?
Редактировать:
- разве
run {}
в приведенном выше примере не то же самое - является ли вызов run дорогостоящим?
ОТВЕТ:
- используя
run {}
встроенные строки, тогда как{}()
ЭТОГО НЕ делает (см. Мой собственный ответ ниже)
Комментарии:
1. «не выполняется {} в приведенном выше примере, по сути, то же самое»: это даст тот же результат, но вызов
run
гарантированно будет встроенным, при выполнении{ ... }()
будет создан объект функции и вызван он.2. @marstran почему создается объект функции? Run также просто вызывает () при передаче лямбда
3. Потому что
run
это встроенная функция. Тело лямбды копируется компилятором на сайт вызова.
Ответ №1:
Используйте run
функцию. Он принимает функцию в качестве параметра, запускает ее и возвращает результат.
val x = run {
... do some complex computations ..
42
}
run
Функция встроена, поэтому у нее не будет накладных расходов на производительность.
Ответ №2:
Да, есть функция run.
val x = run {
...
42
}
Ответ №3:
А также вы также можете использовать эти методы:
val a=1.also{
// your code
}
val b=2.apply{
// your code}
}
val c=3.let{
// your code
}
val d=4.runCatching{
// your code
}
Ответ №4:
Чтобы проверить встраивание при использовании run
, я создал небольшой пример:
fun main() {
{
Math.random()
}()
run {
Math.random()
}
}
и просмотрел созданный байт-код:
public final static main()V
L0
LINENUMBER 2 L0
GETSTATIC TestKt$main$1.INSTANCE : LTestKt$main$1;
CHECKCAST kotlin/jvm/functions/Function0
INVOKEINTERFACE kotlin/jvm/functions/Function0.invoke ()Ljava/lang/Object; (itf)
POP
L1
LINENUMBER 6 L1
L2
L3
L4
ICONST_0
ISTORE 0
L5
LINENUMBER 7 L5
INVOKESTATIC java/lang/Math.random ()D
L6
L7
LINENUMBER 6 L7
L8
POP2
L9
LINENUMBER 9 L9
RETURN
L10
LOCALVARIABLE $i$a$-run-TestKt$main$2 I L5 L7 0
MAXSTACK = 2
MAXLOCALS = 1
Итак, действительно:
- Вызов через
()
вызывает сгенерированныйFunction0
производный класс, который инкапсулирует блок в виде лямбда (меткиL0
) - Вызов через
run
полностью вставляет блок (меткуL5
)