什么时候使用 call-by-name 和 call-by-value? [英] When to use call-by-name and call-by-value?
问题描述
我了解按名称调用和按值调用的基本概念,并且还研究了一些示例.但是,我不太清楚什么时候使用 call-by-name.与其他呼叫类型相比,按名称呼叫将具有显着优势或性能提升的真实场景是什么?设计方法时选择调用类型的正确思路应该是什么?
I understand the basic concept of call-by-name and call-by-value, and I have also looked into handful number of examples. However, I am not very clear about when to use call-by-name. What would be a real-world scenario where call-by-name would have a significant advantage or performance gain over the other call type? What should be the correct thinking approach to select a call type while designing a method?
推荐答案
有很多地方通过名称调用可以获得性能甚至正确性.
There are plenty of places were call-by-name may gain performance or even correctness.
简单的性能示例:日志记录.想象一个这样的界面:
Simple performance example: logging. Imagine an interface like this:
trait Logger {
def info(msg: => String)
def warn(msg: => String)
def error(msg: => String)
}
然后像这样使用:
logger.info("Time spent on X: " + computeTimeSpent)
如果 info
方法没有做任何事情(因为,比如说,日志级别被配置为高于那个),那么 computeTimeSpent
永远不会被调用,从而节省时间.这种情况在记录器中经常发生,人们经常会看到字符串操作相对于正在记录的任务而言可能是昂贵的.
If the info
method doesn't do anything (because, say, the logging level was configured for higher than that), then computeTimeSpent
never gets called, saving time. This happens a lot with loggers, where one often sees string manipulation which can be expensive relative to the tasks being logged.
正确性示例:逻辑运算符.
Correctness example: logic operators.
你可能见过这样的代码:
You have probably seen code like this:
if (ref != null && ref.isSomething)
假设您像这样声明了 &&
方法:
Say you declared &&
method like this:
trait Boolean {
def &&(other: Boolean): Boolean
}
然后,每当 ref
为 null
时,您都会得到一个错误,因为 isSomething
将在 null上被调用code> 引用,然后再传递给
&&
.为此,实际的声明是:
then, whenever ref
is null
, you'll get an error because isSomething
will be called on a null
reference before being passed to &&
. For this reason, the actual declaration is:
trait Boolean {
def &&(other: => Boolean): Boolean =
if (this) other else this
}
所以人们实际上可能想知道什么时候使用按值调用.事实上,在 Haskell 编程语言中,一切都与按名称调用的工作方式相似(相似但不相同).
So one may actually wonder is when to use call-by-value. In fact, in the Haskell programming language everything works similar to how call-by-name works (similar, but not the same).
有充分的理由不使用按名称调用:它更慢,它创建更多的类(意味着程序需要更长的时间来加载),它消耗更多的内存,而且它的不同之处足以让许多人难以推理
There are good reasons not to use call-by-name: it is slower, it creates more classes (meaning the program takes longer to load), it consumes more memory, and it is different enough that many have difficult reasoning about it.
这篇关于什么时候使用 call-by-name 和 call-by-value?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!