Функции контекста Kotlin с запуском расширения
Из того, что я узнал, это похоже на функцию расширения T.run
а также with
имеют одну и ту же цель создания возможности группировать несколько вызовов для одного и того же объекта, возвращая последний объект лямбды в качестве результата.
T.run()
имеет преимущество применения проверки на обнуляемость перед его использованием. (как указывает эта статья)
Каковы преимущества использования with
? или лучше сказать: что мешает мне всегда использовать T.run()
вместо? Спасибо
3 ответа
Это относится ко многим функциям области видимости, вы не всегда можете сказать, какая из них "правильная", на самом деле это выбор разработчика. Что касается with
а также run
единственное отличие состоит в том, как в игру вступает получатель функции scope:
С одной стороны, получатель передается в качестве аргумента with
:
val s: String = with(StringBuilder("init")) {
append("some").append("thing")
println("current value: $this")
toString()
}
С другой стороны, run
напрямую вызывается на приемнике (функция расширения):
val s: String = StringBuilder("init").run {
append("some").append("thing")
println("current value: $this")
toString()
}
run
имеет преимущество обработки обнуляемости, поскольку может применяться безопасный оператор:
val s: String = nullableSB?.run {
//...
} ?: "handle null case"
Я не видел много употреблений run
в то время как with
Я думаю, чаще используется.
Как вы сказали, они функционируют одинаково, кроме возможности использования run
с безопасным вызовом и используя его в цепочечных выражениях, например:
foo.bar().run { qwert() }
Реальная разница заключается в синтаксисе - используйте тот, который обеспечивает лучшую читаемость в вашем коде для вас.
Вы можете положить with
на следующую строку, которая может быть более читабельной, если у вас длинный инициализатор:
val obj = VeryLongInitializer().DoSomething().AnotherThing()
with (obj) {
// Do stuff
}
против
val obj = VeryLongInitializer().DoSomething().AnotherThing().run {
// Do stuff
}