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

本文详细解析了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 的计算。

<think&gt;嗯,用户问的是Scala中的Double =&gt; Boolean是什么意思。首先,我得确认自己对这个概念的理解是否正确。Scala中的类型符号通常用来表示函数类型,所以Double =&gt; Boolean应该是一个函数,接收Double类型的参数,返回Boolean类型的结果。 接下来,用户可能需要具体的例子来理解这个类型的具体应用场景。比如说,在集合的filter方法里,经常需要这样的函数来判断元素是否符合条件。例如,判断一个数是否大于10,可以写成(x: Double) =&gt; x &gt; 10,这时候这个函数的类型就是Double =&gt; Boolean。 然后,用户可能会想知道如何声明这样的函数类型。在Scala中,函数类型的声明方式就是参数类型加上=&gt;和返回类型。所以,Double =&gt; Boolean就是一个函数类型,而具体的函数实例可以是匿名函数或者方法。 另外,用户可能混淆函数类型和方法定义的区别。比如,def isPositive(d: Double): Boolean = d &gt; 0这个方法,如果被赋值给一个变量,它的类型会被自动转换为函数类型,即Double =&gt; Boolean。不过需要注意,方法本身不是函数,但可以转换成函数。 可能还需要解释高阶函数的应用,比如接受Double =&gt; Boolean作为参数的函数,或者返回这种类型的函数。例如,def checkCondition(f: Double =&gt; Boolean, value: Double): Boolean = f(value),这里的f参数就是这种函数类型。 用户可能会有疑问,这样的类型在实际开发中有什么用处。这时候可以举更多的例子,比如在数据处理、条件过滤、验证输入等场景中使用这种函数类型,提高代码的灵活性和复用性。 最后,总结一下,Double =&gt; Boolean在Scala中代表一个从Double到Boolean的函数类型,用于各种需要条件判断的场景,是函数式编程中常见的一种类型。</think&gt;在 Scala 中,`Double =&gt; Boolean` 是一种函数类型(Function Type),其含义可以分解如下: --- ### 1. **语法含义** - **整体结构**:表示一个 **输入为 `Double` 类型,输出为 `Boolean` 类型的函数**。 - **符号解释**: - `=&gt;` 是 Scala 中定义函数类型的符号。 - 左侧 `Double` 是输入参数类型。 - 右侧 `Boolean` 是返回值类型。 --- ### 2. **具体示例** #### 示例 1:直接定义函数 ```scala val isPositive: Double =&gt; Boolean = (x: Double) =&gt; x &gt; 0 ``` - 这里定义了一个函数 `isPositive`,它接受 `Double` 类型的参数 `x`,返回 `x &gt; 0` 的布尔结果。 #### 示例 2:作为方法参数 ```scala def checkNumber(num: Double, predicate: Double =&gt; Boolean): Boolean = { predicate(num) } // 使用示例 checkNumber(3.14, x =&gt; x &gt; 0) // 返回 true ``` - `predicate: Double =&gt; Boolean` 表示参数 `predicate` 是一个函数,它接受 `Double` 参数并返回 `Boolean`。 --- ### 3. **常见使用场景** - **集合操作**:如 `filter` 方法需要 `A =&gt; Boolean` 类型的函数: ```scala val numbers = List(1.5, -2.3, 4.0) numbers.filter(_ &gt; 0) // 等价于 numbers.filter((x: Double) =&gt; x &gt; 0) ``` - **条件验证**:验证数值是否符合特定规则(如范围检查、有效性判断)。 --- ### 4. **与方法的区别** - **方法(Method)**:通过 `def` 定义,属于类/对象的一部分。 ```scala def isEven(d: Double): Boolean = d % 2 == 0 ``` - **函数(Function)**:是一等公民,可赋值给变量或作为参数递。 ```scala val isEvenFunc: Double =&gt; Boolean = d =&gt; d % 2 == 0 ``` --- ### 5. **类型兼容性** - 如果某个方法符合 `Double =&gt; Boolean` 的签名,可通过 `_` 转换为函数: ```scala def isPositiveMethod(d: Double): Boolean = d &gt; 0 val func: Double =&gt; Boolean = isPositiveMethod _ ``` --- ### 总结 `Double =&gt; Boolean` 表示一个 **接受 `Double` 参数并返回 `Boolean` 结果的函数类型**,广泛用于集合操作、条件判断等场景,体现了 Scala 函数式编程的核心特性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值