Scala的解释器在解析函数参数(function arguments)时有两种方式:先计算参数表达式的值(reduce the arguments),再应用到函数内部;或者是将未计算的参数表达式直接应用到函数内部。前者叫做传值调用(call-by-value),后者叫做传名调用(call-by-name)。

传值函数和传名函数

object Add {
def addByName(a: Int, b: => Int) = a + b
def addByValue(a: Int, b: Int) = a + b
}

传名函数和传值函数在编译器中区别:

  addByName(,  + )
-> + ( + )
-> +
-> addByValue(, + )
->addByValue(, )
-> +
->

可以看出,在进入函数内部前,传值调用方式就已经将参数表达式的值计算完毕,而传名调用是在函数内部进行参数表达式的值计算的。

这就造成了一种现象,每次使用传名调用时,解释器都会计算一次表达式的值。对于有副作用(side-effect)的参数来说,这无疑造成了两种调用方式结果的不同。

因此, 在实际的使用中:

传值调用在进入函数体之前就对参数表达式进行了计算,这避免了函数内部多次使用参数时重复计算其值,在一定程度上提高了效率。

但是传名调用的一个优势在于,如果参数在函数体内部没有被使用到,那么它就不用计算参数表达式的值了。在这种情况下,传名调用的效率会高一点。

package com.doggie  

object WhyAlwaysMe {
var flag: Boolean = true
def useOrNotUse(x: Int, y: => Int) = {
flag match{
case true => x
case false => x + y
}
}
def main(args: Array[String]) =
{
println(useOrNotUse(, ))
flag = false
println(useOrNotUse(, ))

=> Unit 与 () =>Unit的区别

简单来说, => Unit是 传名函数, 只传入了一个表达式, 在调用时才会去执行, 使用 code调用

() => 是传值函数, 传入的计算后的值, 使用 code() 调用

package main.scala

/**
* Created by wenbronk on 2017/9/12.
*/
object TestScala { def main(args: Array[String]): Unit = {
// println( addInt(3, 5))
// println(time())
delayTime({
println("");
time()
})
delayTime2({
println("");
time
})
} def delayTime2(t: () => Long): Unit = {
println("执行...")
println( t() )
println("jiesu..")
} def delayTime(t: => Long): Unit = {
println("执行开始")
println(t)
println("执行结束")
} def time() = {
println("获取时间内, 单位为 纳秒")
System.nanoTime()
} }

执行结果:

http://blog.csdn.net/asongoficeandfire/article/details/21889375

http://www.aboutyun.com/thread-10864-1-3.html

http://scalagroup.group.iteye.com/group/topic/26303

scala-传名函数和传值函数的更多相关文章

  1. Scala传名参数(By-Name)

    1.=> 在了解Scala的By-Name参数之前,先了解下“=>”在Scala中有几种用法: 1.对于值,“=>”相当于lambda表达式.如: scala> List(,, ...

  2. scala -- 传名参数

    object Test{ def main(args: Array[String]): Unit = { def test(code : => Unit){// 传名参数 不计算函数值,而是把函 ...

  3. 【Go入门教程3】流程(if、goto、for、switch)和函数(多个返回值、变参、传值与传指针、defer、函数作为值/类型、Panic和Recover、main函数和init函数、import)

    这小节我们要介绍Go里面的流程控制以及函数操作. 流程控制 流程控制在编程语言中是最伟大的发明了,因为有了它,你可以通过很简单的流程描述来表达很复杂的逻辑.Go中流程控制分三大类:条件判断,循环控制和 ...

  4. 【Go入门教程5】流程(if、goto、for、switch)和函数(多个返回值、变参、传值与传指针、defer、函数作为值/类型、Panic和Recover、main函数和init函数、import)

    这小节我们要介绍Go里面的流程控制以及函数操作. 流程控制 流程控制在编程语言中是最伟大的发明了,因为有了它,你可以通过很简单的流程描述来表达很复杂的逻辑.Go中流程控制分三大类:条件判断,循环控制和 ...

  5. C#-函数的传值与传址

    传值就是将实参的值传到所调用的函数里面,实参的值并没有发生变化,默认传值的有int型,浮点型,bool型,char字符型,结构体等等. 传址就是将地址传到所调用的函数里面操作,实参的值也会跟着变化,传 ...

  6. C# 函数的传值与传址(转)

    http://www.cnblogs.com/mdnx/archive/2012/09/04/2671060.html using System; using System.Collections.G ...

  7. scala的传名参数

    scala如果你想实现像if ,while等类似的控制结构,根本没有值要传入花括号{}直接的代码里.要怎么实现. 比如说,我们要实现一个断言的控制结构,myAssert(), myAssert函数参考 ...

  8. Python第七天 函数 函数参数 函数里的变量 函数返回值 多类型传值 函数递归调用 匿名函数 内置函数

    Python第七天   函数  函数参数   函数里的变量   函数返回值  多类型传值     函数递归调用   匿名函数   内置函数 目录 Pycharm使用技巧(转载) Python第一天   ...

  9. python基础----函数的定义和调用、return语句、变量作用域、传参、函数嵌套、函数对象、闭包、递归函数

    1.函数的定义: 函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段. 函数能提高应用的模块性,和代码的重复利用率.你已经知道Python提供了许多内建函数,比如print().但你也可 ...

随机推荐

  1. 【repost】DOM CRUD

    //DOM 的 CRUD // c 创建create // 1.直接往body中动态的添加标签(可以是任意类型)document.write('helloWorld');document.write( ...

  2. jQuery如何获取元素及选择器的参考

    获取元素 Jquery当中几乎所有的功能.选择.事件处理等都用到了这个函数.通常用来获取元素,获取到的元素都会被存储为jQuery对象. 例如: 先设定一个id为aaa的div <body> ...

  3. 从MS Word到Windows Live Writer

    在做笔记的时候,喜欢使用Word进行排版及插入图片,但是当将笔记发布的时候,一般的网站是不支持直接将Word中的图片进行上传的,此时使用Windows Live Writer是一个不错的选择. 可是, ...

  4. 04:第一个OC类

    1.类与对象的关系 面向对象的核心就是对象,那怎么创建对象? OC中创建对象比较复杂, 首先要理解一个概念叫做类. 现实生活中是根据一份描述,一份模板创建对象,编程语言也一样,也必须先有一份描述,在这 ...

  5. iOS笔记之UIKit_UILable

    UILabel*label3 = [[UILabel alloc]initWithFrame:CGRectMake(0, 60+10+60+10+60+10, 320, 60)]; label3.ba ...

  6. sentiwordnet的简单使用

    # Example line: # POS     ID     PosS  NegS SynsetTerm#sentimentscore    Desc # a   00009618  0.5    ...

  7. 微擎开启性能优化里面的性能优化memcache内存优化及数据库读写分离

    http://www.mitusky.com/forum.php?mod=viewthread&tid=3135 [微擎 安装使用] 微擎开启性能优化里面的性能优化memcache内存优化及数 ...

  8. 程序bug导致了天大的损失,要枪毙程序猿吗?[ZZ]

    来自猫扑:程序bug导致了天大的损失,要枪毙程序猿吗? 0 引言 年会上Review 源代码算什么? 法庭上 Review code 才带劲..... 2015年9月3日,随着东京最高法院驳回瑞穗证券 ...

  9. 【Win】Clso QR Tool 二维码小工具

    一个可以生成并识别二维码的windows小工具,纯绿色.不含糖. 可以通过输入文本生成二维码,或者加载本地图片.剪贴板内的图片,直接解析出二维码内容. 支持自定义LOGO. 下载文件 (当前版本:1. ...

  10. c#中快速排序的学习

    最近看了一句话,说的是在现实生活中,会写字的人不见得会写出好文章,学习编程语言就像是学会了写字,学会了编程语言并不一定能写出好程序. 我觉得就是很有道理,以前读书的时候,基本学完了C#中的语法知识,算 ...