谈谈 Scala 函数参数列表中的 => 符号

Scala 的函数定义通常有两种,一种是

def f(x: R)

为传值调用(Call-by-value)。

另一种是

def f(x: => R)

为传名调用(Call-by-name)。

这两者的区别在于,传值调用在进入函数 f 之前,x 的值就已经被计算出来,而传名调用则会等到进入函数 f 内部,执行到有 x 参与的语句时,才计算 x 的值。

举例说明,在 Linux bash 命令行内运行如下命令创建 sbt project 的目录结构

mkdir test_call_project
cd test_call_project
mkdir -p src/{main,test}/scala
mkdir project target
echo 'name := "TestCallProject"
version := "1.0"
scalaVersion := "2.13.1"
scalacOptions := Seq("-unchecked", "-deprecation")' > build.sbt

创建 src/main/scala/TestCallByValueAndName.scala 文件,内容如下:

object TestCallByValueAndName {

   def main(args: Array[String]) : Unit = {

        println("call-by-name:");
        call_by_name(x());
        println("end call-by-name");

        println("\n========\n");

        println("call_by_value:");
        call_by_value(x());
        println("end call_by_value");

    }

    def x() : Long = {
        println("计算 x 的值");
        val y = 2L * 3L;
        y
    }

    def call_by_name( y: => Long ) : Unit = {
        println("在 call_by_name 方法内");
        println("参数:" + y);
    }

    def call_by_value( y : Long ) : Unit = {
        println("在 call_by_value 方法内");
        println("参数:" + y);
    }
}

在 test_call_project 目录下运行

sbt package

编译项目,待编译成功后,运行

sbt run

输出结果如下:

halo:test_call_project klcola$ sbt run
[info] Loading settings for project global-plugins from idea.sbt ...
[info] Loading global plugins from /Users/klcola/.sbt/1.0/plugins
[info] Loading project definition from /Users/klcola/IdeaProjects/learning_scala/test_call_project/project
[info] Loading settings for project test_call_project from build.sbt ...
[info] Set current project to TestCallProject (in build file:/Users/klcola/IdeaProjects/learning_scala/test_call_project/)
[info] Running TestCallByValueAndName
call-by-name:
在 call_by_name 方法内
计算 x 的值
参数:6
end call-by-name

========

call_by_value:
计算 x 的值
在 call_by_value 方法内
参数:6
end call_by_value
[success] Total time: 1 s, completed 2019-9-26 22:44:52

可见传名调用是在进入函数体 call_by_name 才开始函数 x 的计算,而传值调用则在进入函数体 call_by_value 之前就已经完成函数 x 的计算。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值