Scala的偏应用函数

尽管前面的例子里下划线替代的只是单个参数,你还可以使用一个下划线替换整个参数列表。例如,写成println(_),或者更好的方法你还可以写成println _。下面是一个例子:

someNumbers.foreach(println _)

Scala把这种短格式直接看作是你输入了下列代码:

someNumbers.foreach(x => println(x)) 

因此,这个例子中的下划线不是单个参数的占位符。它是整个参数列表的占位符。请记住要在函数名和下划线之间留一个空格,因为不这样做编译器会认为你是在说明一个不同的符号,比方说是,似乎不存在的名为println_的方法。

以这种方式使用下划线时,你就正在写一个偏应用函数:partially applied function。Scala里,当你调用函数,传入任何需要的参数,你就是在把函数应用到参数上。如,给定下列函数:

scala> def sum(a: Int, b: Int, c: Int) = a + b + c
sum: (Int,Int,Int)Int  

你就可以把函数sum应用到参数1,2和3上,如下:

scala> sum(1, 2, 3)
res12: Int = 6 

偏应用函数是一种表达式,你不需要提供函数需要的所有参数。代之以仅提供部分,或不提供所需参数。比如,要创建不提供任何三个所需参数的调用sum的偏应用表达式,只要在“sum”之后放一个下划线即可。然后可以把得到的函数存入变量。举例如下:

scala> val a = sum _  
a: (Int, Int, Int) => Int = < function>  

有了这个代码,Scala编译器以偏应用函数表达式,sum _,实例化一个带三个缺失整数参数的函数值,并把这个新的函数值的索引赋给变量a。当你把这个新函数值应用于三个参数之上时,它就转回头调用sum,并传入这三个参数:

scala> a(1, 2, 3)
res13: Int = 6

实际发生的事情是这样的:名为a的变量指向一个函数值对象。这个函数值是由Scala编译器依照偏应用函数表达式sum _,自动产生的类的一个实例。编译器产生的类有一个apply方法带三个参数。产生的类扩展了特质Function3,定义了三个参数的apply方法。之所以带三个参数是因为sum _表达式缺少的参数数量为三。Scala编译器把表达式a(1,2,3)翻译成对函数值的apply方法的调用,传入三个参数1,2,3。因此a(1,2,3)是下列代码的短格式:

scala> a.apply(1, 2, 3)
res14: Int = 6 

时间: 2024-08-04 01:55:51

Scala的偏应用函数的相关文章

scala 学习笔记(01) 函数定义、分支、循环、异常处理、递归

package yjmyzz import scala.io.StdIn object ScalaApp { def main(args: Array[String]) { println("please input something,press Enter to exit:") //每一行最后加不加分号都可以 readKeyboard //注:无参数的函数调用,加不加括号都行 println(add(1, 2) + "\n------\n") println(d

Coursera Scala 2-2:Curry函数

Curry函数,将一个函数的参数,拆分成多个.概念不好理解,还是用代码最好.如下: 乘积函数 有一个乘积函数,计算a~b基于函数f转化后的值的乘积 def product(f:Int=>Int)(a:Int,b:Int): Int = if( a > b ) 1 else f(a) * product(f)(a + 1, b) 这样做可以让函数复用,比如: def factorial(n: Int) = product(x => x)(1, n) 之后,我们就可以专心将这个curry函数

Java为函数调度添加功能和间接引用

局部套用 和部分应用 是来源于数学的语言技术(基于 20 世纪数学家 Haskell Curry 和其他人的工作成果).这两种技术存在于各种类型的语言中,可以单独或同时存在于函数式语言中.局部套用和部分应用使您能够处理函数或方法的参数数量,通常的方法是为一些参数提供一个或多个默认值(称为修正 参数).所有 Java 下一代语言都包括局部套用和部分应用,但以不同的方式实现它们.在本文中,我将介绍这两种技术的不同之处,并展示它们在 http://www.aliyun.com/zixun/aggreg

Scala函数特性

通常情况下,函数的参数是传值参数:即参数的值在它被传递给函数之前被确定.但是,如果我们需要编写一个接收参数不希望马上计算,直到调用函数内的表达式才进行真正的计算的函数.对于这种情况,Scala提供按名称参数调用函数. 示例代码如下:   结果:   在代码中,如果定义函数的时候,传入参数不是传入的值,而是传入的参数名称(如代码中使用t: => Long而不是t: Long),在调用该函数时,不会立即执行和参数有关的计算,而是到参数真正使用到的时候才进行计算.   结果说明:主函数调用delaye

Scala基本语法和概念

本文主要包括Scala的安装过程并理解Scala的基本语法和概念,包括表达式.变量.基本类型.函数.流程控制等相关内容. 1. 安装 从All Versions Scala下载所需版本Scala安装包,解压到指定目录之后,配置环境变量并使其生效. 如果你使用Mac,则可以使用brew安装: ⇒ brew install scala 在终端键入scala查看Scala的版本,并进入Scala的解释器: ⇒ scala Welcome to Scala version 2.11.6 (Java Ho

Scala程序设计读书笔记[6:10]

第六章 函数值和闭包 高阶函数 以其它函数为参数的函数. 函数值 可以在函数里创建函数,将函数赋给引用.函数参数中例如codeBlock: Int => Int.函数值包含多行代码或者作为参数传入时有多个参数,需要用圆括号包起来. 具有多参数值的函数值 具有多个参数的函数值例如operation: (Int, Int) => Int).想要遍历容器中元素,执行一些操作可以使用foldLeft方法,即/:.使用方法,0为初值:array.foldLeft(0){},(0 /: array){}.

Scala入门到精通——第二十五节 提取器(Extractor)

作者:摇摆少年梦 视频地址:http://www.xuetuwuyou.com/course/12 本节主要内容 apply与unapply方法 零变量或变量的模式匹配 提取器与序列模式 scala中的占位符使用总结 1. apply与unapply方法 apply方法我们已经非常熟悉了,它帮助我们无需new操作就可以创建对象,而unapply方法则用于析构出对象,在模式匹配中特别提到,如果一个类要能够应用于模式匹配当中,必须将类声明为case class,因为一旦被定义为case class,

Scala介绍之HelloWorld

Scala语言的名称来自于"可伸展的语言",Scala 是一种函数对象混合的语言.它可以运行在Java 平台上,Scala程序会被编译为JVM的字节码.它们的执行期性能通常与Java程序一致.Scala代码可以调用Java方法,访问Java字段,继承自Java类和实现Java接口 下载并安装 Scala 可以从 Scala 主页: http://www.scala-lang.org/ 下载 Scala 包,截止到目前为止,最新的发行版是 2.7.5-final,同时也提供了IDE的支持

Scala允许的重复参数

Scala允许你指明函数的最后一个参数可以是重复的.这可以允许客户向函数传入可变长度参数列表 .想要标注一个重复参数,在参数的类型之后放一个星号.例如: scala> def echo (args: String*) = for (arg < - args) println(arg) echo: (String*)Unit 这样定义,echo可以被零个至多个String参数调用: scala> echo() scala> echo("one") one scal