Котлин: Применить против С
В чем разница между ними и их применением. Из того, что я знаю, следующий код делает то же самое:
swingElement.apply {
minWidth = ENABLED_COLUMN_WIDTH
maxWidth = ENABLED_COLUMN_WIDTH
preferredWidth = ENABLED_COLUMN_WIDTH
}
with(swingElement) {
minWidth = ENABLED_COLUMN_WIDTH
maxWidth = ENABLED_COLUMN_WIDTH
preferredWidth = ENABLED_COLUMN_WIDTH
}
Есть ли разница, и я должен использовать один над другим?
Кроме того, есть ли случаи, когда можно было бы работать, а другой - нет?
Ответы
Ответ 1
Есть два отличия:
-
apply
принимает экземпляр в качестве получателя, а with
требует, чтобы экземпляр передавался как аргумент. В обоих случаях экземпляр станет this
внутри блока.
-
apply
возвращает получатель, а with
возвращает результат последнего выражения внутри своего блока.
Я не уверен, что могут быть какие-то строгие правила, какие функции выбрать. Обычно вы используете apply
, когда вам нужно что-то делать с объектом и возвращать его. И когда вам нужно выполнить некоторые операции над объектом и вернуть какой-либо другой объект, вы можете использовать либо with
, либо run
. Я предпочитаю run
, потому что это более читаемо, на мой взгляд, но это вопрос вкуса.
Ответ 2
Функция apply
//returns receiver T, T exposed as 'this'
fun <T> T.apply(block: T.() -> Unit): T
Описание
apply
функция вызывается на приемнике T
, который будет выставлен, как this
в пройденному лямбда - выражения. Получатель также становится результатом apply
автоматически.
with
функцией
//return arbitrary value R, not an extension function, T exposed as 'this'
fun <T, R> with(receiver: T, block: T.() -> R): R
Описание
Функция with
, в отличие от всех других функций области действия (let
, run
, also
, apply
), не определена как функция расширения. Вместо этого функция вызывается с объектом-получателем в качестве первого аргумента в явном виде. То же самое apply
, приемник подвергается воздействию, как this
в пройденному лямбда. Результат лямбда, то есть его последнее утверждение, становится результатом (R
) с with
.
Ответ 3
Вот сходства и различия
сходства
С и Применить оба принимают объект в качестве получателя независимо от того, как они передаются.
Различия
С возвращает последнюю строку в лямбда-выражении как результат выражения.
Apply возвращает объект, который был передан в качестве получателя в результате лямбда-выражения.
Примеры
С
private val ORIENTATIONS = with(SparseIntArray()) {
append(Surface.ROTATION_0, 90)
append(Surface.ROTATION_90, 0)
append(Surface.ROTATION_180, 270)
append(Surface.ROTATION_270, 180)
}
ORIENTATIONS[0] // doesn't work
// Here, using with prevents me from accessing the items in the SparseArray because,
// the last line actually returns nothing
Применять
private val ORIENTATIONS = SparseIntArray().apply {
append(Surface.ROTATION_0, 90)
append(Surface.ROTATION_90, 0)
append(Surface.ROTATION_180, 270)
append(Surface.ROTATION_270, 180)
}
ORIENTATIONS[0] // Works
// Here, using apply, allows me to access the items in the SparseArray because,
// the SparseArray is returned as the result of the expression