Используйте расширения-мою библиотеку схему:
implicit class SideEffectPassthrough[A](val a: A) extends AnyVal {
def se(sideEffectFunction: A => Unit): A = {
sideEffectFunction(a)
a
}
}
def compute(a: Int) = a + 2 + 3
val x = compute(1).se(println)
// x: Int = 6
компилятор сделает упаковку для вас, делая уборщик синтаксиса. Обратите внимание, что когда мы добавляем extends AnyVal
, мы фактически гарантируем, что компилятор перепишет этот код так, чтобы он буквально не делал никаких оберток, вместо этого он создаст статическую функцию для обработки поведения, что означает меньшую накладную часть времени выполнения, поскольку ни один объект обертка не нужно будет создавать экземпляры)
sideEffectFunction
аргумент se
может быть любой произвольной функции, до тех пор, как он принимает, как это аргумент, результат предыдущего выражения:.
val y = compute(1).se { r =>
println("Performing a side effect now!")
println(r)
}
// y: Int = 6
Просто для полноты, вот иная w ау для достижения тех же целей:
def printAndReturn[A](block: => A): A = {
val result = block
println(result)
result
}
val x = printAndReturn(1+2+3)
// x: Int = 6
val y = printAndReturn {
val a = 1 + 2
a + 3
}
// y: Int = 6
Аргумента block
может быть любым произвольным выражением, в том числе любого произвольного блока кода. Обратите внимание, что он передается по имени, поэтому он оценивается внутри se
.
Похоже [Kestrel комбинатора] (http://combinators.info/#kestrels) –
@ PatrykĆwiek но ... но это * рубин *: O –
@ Золтан Ну, это достаточно читаемый и [есть и другие вопросы и ответы, адресованные ему в Scala] (http://stackoverflow.com/a/9673294/1180426) :) –