斯卡拉(Scala):请用我的名字给我打电话?

在Java中,当诸如log4J之类的框架在Java体系结构中变得流行时,经常会看到诸如以下代码:

if (logger.isEnabledFor(Logger.INFO)) {
   // Ok to log now.
   logger.info('ok' + 'to' + 'concatenate'  + 'string' + 'to' + 'log' + 'message');
}

在执行任何String串联之前,始终检查是否为适当级别启用了日志记录是最佳实践。 我什至还记得十年前的一个项目(爱立信的3G无线电网络配置工具),该项目中用于记录日志的字符串连接实际上导致性能显着下降。

从那时起,JVM进行了优化,并且摩尔定律不断发展,因此String串联不再像以前那样令人担忧。 在许多框架(例如Hibernate )中,如果您检查源代码,则会看到日志记录代码,而无需检查是否启用了日志记录,并且无论如何都会进行字符串连接。 但是,让我们假装串联是一个性能问题。 我们真正想做的是消除对if语句的需要,以停止代码膨胀。 这里的问题是,在Java中,当您调用带有参数的方法时,所有参数的值都是在调用该方法之前计算出来的。 这就是为什么需要if语句的原因。

simpleComputation(expensiveComputation());// In Java, the expensive computation is called first.
logger.log(Level.INFO, 'Log this ' + message);// In Java, the String concatenation happens first

Scala提供了一种可以延迟参数评估的机制。 这称为“ 按名称呼叫”

def log(level: Level, message: => String) = if (logger.level.intValue >= level.intValue) logger.log(level, msg)

字符串类型前的=>表示在调用日志函数之前不会评估字符串参数。 相反,将进行检查以确认记录器级别的值处于适当的值,如果是,则将评估字符串。 该检查在log功能中进行,因此无需在每次调用前都放置该检查。 那代码重用呢?

还要别的吗?

是的,当使用传递名称时,传递名称的参数不仅会被评估一次,而且会在传递给函数的函数中每次被引用时进行评估。 让我们看另一个例子

scala> def nanoTime() = {
     |   println(">>nanoTime()")
     |   System.nanoTime // returns nanoTime
     | }
nanoTime: ()Long
 
scala> def printTime(time: => Long) = {    // => indicates a by name parameter
     |   println(">> printTime()")
     |   println("time= " + time)
     |   println("second time=" + time)
     |   println("third time=" + time)
     | }
printTime: (time: => Long)Unit
 
 
scala> printTime(nanoTime())
 
>> printTime()
>>nanoTime()
time= 518263321668117
>>nanoTime()
second time=518263324003767
>>nanoTime()
third time=518263324624587

在这个例子中,我们可以看到nanoTime()不仅执行一次,而且每次在函数printTime被引用时printTime被执行。 这意味着它在此函数中执行了三次,因此我们得到了三个不同的时间。 直到下一次,保重身体。

参考: Scala:请以我的名字叫我? 从我们的JCG合作伙伴 Alex Staveley在都柏林的技术博客博客中获得。

翻译自: https://www.javacodegeeks.com/2013/01/scala-call-me-by-my-name-please.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值