(数据科学学习手札48)Scala中的函数式编程
一、简介
Scala作为一门函数式编程与面向对象完美结合的语言,函数式编程部分也有其独到之处,本文就将针对Scala中关于函数式编程的一些常用基本内容进行介绍;
二、在Scala中定义函数
2.1 定义函数
和Python相似,Scala中函数的定义和方法(类中的函数称为方法)都以关键词def开始,后面再跟随函数名、函数参数以及参数类型、返回值类型以及函数执行体部分,这是Scala中最常规的函数的定义方法,下面是一个简单的例子:
object main{
def main(args: Array[String]): Unit = {
//定义函数
def plus(a:Double,b:Double):Double={
a + b
}
var result:Double = 0
//调用函数计算结果
result = plus(5,4)
println(result)
}
}
上例中,我们以def关键字开头,定义了一个函数名为plus,传入参数为Double型的a,Double型的b,传出类型为Double型的函数用于计算两个数字之和,运行上述代码,得到对应的结果:

我们也可以定义不含输入参数和返回值的函数:
object main{
def main(args: Array[String]): Unit = {
//定义函数
def demo():Unit={
println("这是个演示函数")
}
demo()
}
}
这时返回值的类型就变为Unit,即无类型,运行结果如下:

当函数执行体部分只有一条语句时,可以直接省略花括号来定义函数,如下面这个例子:
object main{
def compare(a:Double,b:Double)=if(a > b) a else b
def main(args: Array[String]): Unit = {
println("更大的数是"+compare(3,4))
}
}
更特别的,在Scala中我们可以对类中的方法进行条件限制,即先决条件,使用在类中定义方法同等层次下,定义require(表达式内容),来对使用到require中表达式限制的参数进行限制,只有满足条件才会运行对应函数,下面是一个简单的例子:
object main{
class Demo(a:Double,b:Double){
require(a != b)
def compare(): Double ={
if(a > b) a else b
}
}
def main(args: Array[String]): Unit = {
//满足条件地调用
val demo1 = new Demo(a=4,b=3)
println(demo1.compare())
//不满足条件的调用
try{
val demo2 = new Demo(a=4,b=4)
println(demo2.compare())
}catch {
case ex:Exception => println(ex)
}
}
}
可以看出,第一次调用Demo中的compare函数,传入的参数满足 a!=b,因此函数顺利得到执行,而第二次调用时未满足条件,使得程序报错,被错误处理机制所捕获,运行结果如下;

2.2 本地函数
有时候为了函数名之间不发生重名的冲突,我们会在Scala中使用本地函数的机制,顾名思义,本地函数指的是只可以在某部分作用域内调用的函数,如下面这个简单的例子:
object main{
def main(args: Array[String]): Unit = {
def X(): Unit ={
//在常规函数内部定义本地函数
def Y(): Unit ={
println("这是本地函数Y")
}
//在常规函数内部调用本地函数
Y()
}
def Y(): Unit ={
println("这是非本地函数Y")
}
//分别调用X,Y
X()
Y()
}
}
如上,我们定义了两个函数名均为Y的函数,第一个Y是函数X内部的本地函数,第二个Y是常规函数,当我们在常规函数X中调用其拥有的本地函数Y时,便不会引起与外部同名Y函数之间的冲突,运行结果如下:

2.3 匿名函数
在Scala中也有匿名函数的机制,使得我们只需要书写简单的语句就可以在程序中嵌入需要实现的函数功能,下面是一个简单的例子:
object main{
def main(args: Array[String]): Unit = {
//在List的定义过程中使用匿名函数和map方法来转换所有值
var listDemo = List(1,2,3).map((x:Int) => x+1)
println(listDemo)
}
}
在上例中,我们在一个List的定义过程中,利用map方法,将匿名函数 (x:Int) => x+1 广播到List中所有元素之上,运行结果如下:

在Scala中,我们可以将匿名函数作为值进行传递,这称为函数字面量,在函数编译函数字面量的时候才将其实例化为函数值,有些类似类,下面是一个简单的例子:
object main{
def main(args: Array[String]): Unit = {
//定义一个匿名函数并将它传递给变量MyFunction
var MyFunction = (x:Int,n:Int) => {
var result = x
for(i <- 1 until n){
result *= x
}
result
}
//调用保存匿名函数字面量的变量
var TestValue = MyFunction(2,10)
println(TestValue)
}
}
在上例中,我们定义了一个用于求一个整数若干次方的函数,并将其传递给变量MyFunction,接着调用MyFunction来传入计算结果,作为新变量的值。
2.4 高阶函数
高阶函数是Scala的函数式编程中十分有趣的一部分,它的基本特点是将其他函数作为当前函数的参数来传入,下面是一个简单的关于高阶函数部分特性的例子:
object main{
def main(args: Array[String]): Unit = {
//定义函数字面量并赋值
var func1 = (x:Int, n:Int) => {
var result = x
for(i <- 1 until n){
result *= x
}
result
}
//定义高阶函数
def func2(MyFunction:(Int,Int)=>Int,x:Int,n:Int): Int ={
MyFunction(x,n)
}
//调用高阶函数,传入函数字面量并打印结果
println(func2(func1,2,10))
}
}
在上例中我们定义了函数字面量并传递给func1,接着定义了函数func2,设置func2的第一个传入参数为接受两个Int型输入,输出Int型数据的函数,设置func2的2、3个参数为Int型,以对应第一个参数中的函数需要传入的参数,接着我们将函数字面量func1、2,、10作为func2的参数传入func1中,得到了对应的结果。
以上就是Scala中函数式编程的一些基本内容,如有笔误,望指出。
(数据科学学习手札48)Scala中的函数式编程的更多相关文章
- (数据科学学习手札32)Python中re模块的详细介绍
一.简介 关于正则表达式,我在前一篇(数据科学学习手札31)中已经做了详细介绍,本篇将对Python中自带模块re的常用功能进行总结: re作为Python中专为正则表达式相关功能做出支持的模块,提供 ...
- (数据科学学习手札42)folium进阶内容介绍
一.简介 在上一篇(数据科学学习手札41)中我们了解了folium的基础内容,实际上folium在地理信息可视化上的真正过人之处在于其绘制图像的高度可定制化上,本文就将基于folium官方文档中的一些 ...
- (数据科学学习手札49)Scala中的模式匹配
一.简介 Scala中的模式匹配类似Java中的switch语句,且更加稳健,本文就将针对Scala中模式匹配的一些基本实例进行介绍: 二.Scala中的模式匹配 2.1 基本格式 Scala中模式匹 ...
- (数据科学学习手札44)在Keras中训练多层感知机
一.简介 Keras是有着自主的一套前端控制语法,后端基于tensorflow和theano的深度学习框架,因为其搭建神经网络简单快捷明了的语法风格,可以帮助使用者更快捷的搭建自己的神经网络,堪称深度 ...
- (数据科学学习手札69)详解pandas中的map、apply、applymap、groupby、agg
*从本篇开始所有文章的数据和代码都已上传至我的github仓库:https://github.com/CNFeffery/DataScienceStudyNotes 一.简介 pandas提供了很多方 ...
- (数据科学学习手札55)利用ggthemr来美化ggplot2图像
一.简介 R中的ggplot2是一个非常强大灵活的数据可视化包,熟悉其绘图规则后便可以自由地生成各种可视化图像,但其默认的色彩和样式在很多时候难免有些过于朴素,本文将要介绍的ggthemr包专门针对原 ...
- (数据科学学习手札50)基于Python的网络数据采集-selenium篇(上)
一.简介 接着几个月之前的(数据科学学习手札31)基于Python的网络数据采集(初级篇),在那篇文章中,我们介绍了关于网络爬虫的基础知识(基本的请求库,基本的解析库,CSS,正则表达式等),在那篇文 ...
- (数据科学学习手札47)基于Python的网络数据采集实战(2)
一.简介 马上大四了,最近在暑期实习,在数据挖掘的主业之外,也帮助同事做了很多网络数据采集的内容,接下来的数篇文章就将一一罗列出来,来续写几个月前开的这个网络数据采集实战的坑. 二.马蜂窝评论数据采集 ...
- (数据科学学习手札40)tensorflow实现LSTM时间序列预测
一.简介 上一篇中我们较为详细地铺垫了关于RNN及其变种LSTM的一些基本知识,也提到了LSTM在时间序列预测上优越的性能,本篇就将对如何利用tensorflow,在实际时间序列预测任务中搭建模型来完 ...
随机推荐
- Git在eclipse中的配置
1:git在eclipse中的配置 windows - >preferences->team->git->configuration 点击add Entry key值:输入 u ...
- 初始python(一)
一.python特性概要 1. python是解释性脚本语言. 2. python特性总结 2.1 字节码 2.2 动态语义 在赋值是确定数据类型 2.3 缩进(4个空格) 3. python定义编码 ...
- python安装 numpy&安装matplotlib& scipy
numpy安装 下载地址:https://pypi.python.org/pypi/numpy(各取所需) copy安装目录.eg:鄙人的D:\python3.6.1\Scripts pip inst ...
- 获取应用程序 或Web页面目录的路径
一.Winform获取本程序的路径 1.获取当前目录 返回最后不带“\”的目录:如D:\Winform\bin\Debug System.Windows.Forms.Application.Start ...
- SQL脚本修改表结构
SQL脚本修改表结构 新建表:create table [表名]([自动编号字段] int IDENTITY (1,1) PRIMARY KEY ,[字段1] nVarChar(50) default ...
- KMP算法模板&&扩展
很不错的学习链接:https://blog.csdn.net/v_july_v/article/details/7041827 具体思路就看上面的链接就行了,这里只放几个常用的模板 问题描述: 给出字 ...
- 关于Struts2通配符无效的说明
在struts2.3之前的版本,正常的配置就可以了,但在struts2.3版本之后,使用通配符调用方法时,内部会验证是否允许访问该方法. 1.struts2.5 为了增加安全性,在 struts.xm ...
- jQuery Datatable 表格插件
Datatable 总体来说很好用,可以实现即时搜索和排序.但是只能用于数据量较少的情况下,如果数据量超过1K建议还是用表格加翻页,不然会很慢. datatable 中文网 http://datat ...
- office2013密钥
GYWDG-NMV9P-746HR-Y2VQW-YPXKK6HDB9-BNRGY-J3F83-CF43C-D67TXG9N3P-GRJK6-VM63J-F9M27-KHGXKX2YWD-NWJ42-3 ...
- Eclipse导入web项目发布项目时报Tomcat version 7.0 only supports J2EE 1.2, 1.3, 1.4, and Java EE 5 and 6 Web错误解决方案
Eclipse导入web项目后,将web项目加载到server进行发布时,提示Tomcat version 7.0 only supports J2EE 1.2, 1.3, 1.4, and Java ...