Khi lập trình bằng java, tôi luôn ghi thông số đầu vào và giá trị trả về của phương thức, nhưng trong scala, dòng cuối cùng của phương thức là giá trị trả về. vì vậy tôi phải làm một cái gì đó như:cách giữ giá trị trả về khi đăng nhập scala
def myFunc() = {
val rs = calcSomeResult()
logger.info("result is:" + rs)
rs
}
để làm cho nó dễ dàng, tôi viết một tiện ích:
class LogUtil(val f: (String) => Unit) {
def logWithValue[T](msg: String, value: T): T = { f(msg); value }
}
object LogUtil {
def withValue[T](f: String => Unit): ((String, T) => T) = new LogUtil(f).logWithValue _
}
Sau đó, tôi sử dụng nó như là:
val rs = calcSomeResult()
withValue(logger.info)("result is:" + rs, rs)
nó sẽ đăng nhập giá trị và trả lại. nó có hiệu quả đối với tôi, nhưng có vẻ lạ lùng. như tôi là một lập trình viên java cũ, nhưng mới với scala, tôi không biết liệu có một cách thành ngữ hơn để làm điều này trong scala.
nhờ sự giúp đỡ của bạn, bây giờ tôi có thể tạo một tốt hơn thông số util sử dụng Kestrel combinator metioned bởi romusz
object LogUtil {
def kestrel[A](x: A)(f: A => Unit): A = { f(x); x }
def logV[A](f: String => Unit)(s: String, x: A) = kestrel(x) { y => f(s + ": " + y)}
}
tôi thêm f để tôi có thể vượt qua nó một logger từ slf4j, và các trường hợp thử nghiệm là:
class LogUtilSpec extends FlatSpec with ShouldMatchers {
val logger = LoggerFactory.getLogger(this.getClass())
import LogUtil._
"LogUtil" should "print log info and keep the value, and the calc for value should only be called once" in {
def calcValue = { println("calcValue"); 100 } // to confirm it's called only once
val v = logV(logger.info)("result is", calcValue)
v should be === 100
}
}
Tại sao không sử dụng AspectJ? Vâng, nó không phải là Scala, đó là sự thật. –