登录Scala时如何保持返回值
发布时间:2020-12-16 09:36:00 所属栏目:安全 来源:网络整理
导读:在java编程时,我总是记录输入参数和方法的返回值,但是在scala中,方法的最后一行是返回值。所以我必须做一些像: def myFunc() = { val rs = calcSomeResult() logger.info("result is:" + rs) rs} 为了使它变得容易,我写了一个实用程序: class LogUtil(
在java编程时,我总是记录输入参数和方法的返回值,但是在scala中,方法的最后一行是返回值。所以我必须做一些像:
def myFunc() = { val rs = calcSomeResult() logger.info("result is:" + rs) rs } 为了使它变得容易,我写了一个实用程序: 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 _ } 然后我用它: val rs = calcSomeResult() withValue(logger.info)("result is:" + rs,rs) 它将记录该值并返回。它适用于我,但似乎很厉害。因为我是一个老的java程序员,而是新的scala,我不知道在scala中是否有更为惯用的方法来做到这一点。 感谢您的帮助,现在我使用由romusz决定的Kestrel组合器创建一个更好的工具 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)} } 我添加f参数,以便我可以从slf4j传递一个记录器,测试用例是: 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 } } 解决方法
你要找的是Kestrel组合器(K组合器):Kxy = x。您可以在返回传递给它的值时,进行各种副作用(不仅记录)操作。阅读
https://github.com/raganwald/homoiconic/blob/master/2008-10-29/kestrel.markdown#readme
在Scala中,实现它的最简单的方法是: def kestrel[A](x: A)(f: A => Unit): A = { f(x); x } 然后可以将打印/记录功能定义为: def logging[A](x: A) = kestrel(x)(println) def logging[A](s: String,x: A) = kestrel(x){ y => println(s + ": " + y) } 并使用它像: logging(1 + 2) + logging(3 + 4) 您的示例功能成为单行: def myFunc() = logging("result is",calcSomeResult()) 如果您喜欢OO符号,可以使用其他答案所示的含义,但是这种方法的问题是,每当您想记录某些东西时,您都将创建一个新对象,如果您经常使用它,可能会导致性能下降。但为了完整,它看起来像这样: implicit def anyToLogging[A](a: A) = new { def log = logging(a) def log(msg: String) = logging(msg,a) } 使用它像: def myFunc() = calcSomeResult().log("result is") (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
相关内容