scala(一)方法&函数
写在前面
众所周知,scala一向宣称自己是面向函数的编程,(java表示不服,我是面向bean的编程!)那什么是函数?
在接触java的时候,有时候用函数来称呼某个method(实在找不出词了),有时候用方法来称呼某个method,虽然method的中文翻译就是“方法”,但对于java来说,方法和函数是等价的,或者说没有函数这个概念。
而对于scala,这两者似乎有一个较为明确的边界。
你会发现满世界的函数,而你却在写方法
Scala 方法&函数
方法
Scala的方法和java可以看成是一样的,只是多了点语法糖。
比如无参方法在申明时可以不加括号,甚至在调用过程也不用加括号
def f = 1+1
println(f)
比如方法可以添加泛型规则,这在java中只能在类申明
def f[T](t: T) = {t}
还有其它很多细节语法,遇到才深入吧
一般而言只要知道函数的结构就行(但是我想说,spark的代码就没有一个函数长成这样的啊..),请忽略下图的“函数”字样,其实就是方法
方法应用
def method(): Unit ={
//本地方法
def print(str:String): Unit ={
println(str)
}
print("hello")
}
方法的语法还是跟java差不多的,只是有些可以省略而已。
比较重要的就是本地方法,即方法中嵌套方法
函数
Scala的函数是基于Function家族,0-22,一共23个Function Trait可以被使用,数字代表了Funtcion的入参个数
函数语法
下面这四个函数的意义是一样的
// println(fun1)
// println(fun2)
// println(fun3)
// println(fun4)
// 都为<function2>
val fun1 = new Function2[Int,Int,Int]() {
override def apply(v1: Int, v2: Int): Int = {
v1+v2
}
} val fun2 = new ((Int, Int) => Int)() {
override def apply(v1: Int, v2: Int): Int = {
v1+v2
}
} val fun3 = (v1:Int,v2:Int) => v1+v2 // _可以把method转换成function
val fun4 = fun4Method _
def fun4Method(v1:Int,v2:Int): Int = {
v1+v2
}
一般我们都采用第三种fun3定义方式,也是最难懂的一个定义方式。具体结构参考下图
那函数有什么用呢?
Java里只有方法都能适应一切需求,那scala又提出函数的概念肯定有意义。
1.函数可以直接赋值给变量,可以让函数很方便的传递
2.闭包(closure),可以把灵活操作代码块,从而引申出其他灵活的语法
函数应用
在spark中,有很多方法入参中使用函数的场景,比如如下函数
defrunJob[T,U](fun: Iterator[T] => U ,resHandler: (Int, U) => Unit): Unit ={
//忽略里面的逻辑
}
其中的fun和resHandler都是函数
Fun是入参为Iterator[T],返回值为U的函数,一个入参的函数其实就是Function1的实例
resHandler是入参为Int和 U无返回值的函数,二个入参的函数其实就是Function2
模拟spark中常见的一段代码语法,拿一个普通scala类型的例子来说
//模拟spark的runJob方法
def runJob[T,U](fun: Iterator[T] => U ,resHandler: (Int, U) => Unit): Unit ={
val listBuffer = new ListBuffer[T]
listBuffer.append("h".asInstanceOf[T])
listBuffer.append("e".asInstanceOf[T])
listBuffer.append("l".asInstanceOf[T])
listBuffer.append("l".asInstanceOf[T])
listBuffer.append("o".asInstanceOf[T])
//这里调用函数其实用到了伴生对象的概念,fun(xxx)就是fun.apply(xxx)
val res = fun(listBuffer.iterator)
//spark中,这里是每个partition的数据都存入arr,这里做模拟就一个partition了:)
resHandler(0,res)
} //模拟调用runJob的方法
def main(args: Array[String]): Unit = {
val arr = new Array[String](1)
//fun函数的实际逻辑
val fun = (it:Iterator[String]) => {
val sb = new StringBuilder()
while (it.hasNext)
sb.append(it.next())
sb.toString()
} //resHandler函数的实际逻辑
val resHandler = (i:Int,res:String) => arr(i) = res
runJob[String,String](fun ,resHandler)
println(arr.mkString(""))
}
其实就是传递函数的逻辑,和java的匿名类差不多(只有一个方法的匿名类),只是多了点语法糖
这么做的好处也是不言而喻的
1.可以构造出更抽象的方法,使得代码结构更简洁
2.spark的思想就是lazy,而函数传递也是一个lazy的过程,只有在实际触发才会执行
偏函数
英文为PartialFunction,不知道这么翻译对不对,貌似都这么叫。
PartialFunction其实是Funtion1的子类
参考源码
trait PartialFunction[-A, +B] extends (A => B)
A => B就是标准的函数结构
那PartialFunction有什么作用呢?
模式匹配!
PartialFunction最重要的两个方法,一个是实际的操作逻辑,一个是校验,其实就是用来做模式匹配的。
参考资料
《Scala编程》
scala(一)方法&函数的更多相关文章
- 【Scala篇】--Scala中的函数
一.前述 Scala中的函数还是比较重要的,所以本文章把Scala中可能用到的函数列举如下,并做详细说明. 二.具体函数 1.Scala函数的定义 def fun (a: Int , b: Int ) ...
- Scala函数式编程(三) scala集合和函数
前情提要: scala函数式编程(二) scala基础语法介绍 scala函数式编程(二) scala基础语法介绍 前面已经稍微介绍了scala的常用语法以及面向对象的一些简要知识,这次是补充上一章的 ...
- Scala高阶函数与泛型
1. Scala中的函数 在Scala中,函数是“头等公民”,就和数字一样.可以在变量中存放函数,即:将函数作为变量的值(值函数). 2. scala中的匿名函数,即没有函数名称的函数,匿名函数常作为 ...
- scala def方法时等号和括号使用说明笔记
scala定义方法时会指定入参和返回类型(无返回类型时对应Unit,即java和C中的void模式). 1.有入参,有返回类型时,scala具有类型推导功能,以下两种表达方式效果一样.但根据scala ...
- scala编程(八)——函数和闭包
当程序变得庞大时,你需要一些方法把它们分割成更小的,更易管理的片段.为了分割控制流,Scala 提供了所有有经验的程序员都熟悉的方式:把代码分割成函数.实际上,Scala 提供了许多 Java 中没有 ...
- Scala 深入浅出实战经典 第42讲:scala 泛型类,泛型函数,泛型在spark中的广泛应用
王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-64讲)完整视频.PPT.代码下载:百度云盘:http://pan.baidu.com/s/1c0noOt6 ...
- <经验杂谈>C#中一种最简单、最基本的反射(Reflection):通过反射获取方法函数
说起反射之前和很多用C#/.net的同仁们一样,相比于一般应用层对数据的增删改查总有点觉得深奥到难以理解.其实程序这东西,用过.实践过就很简单,我一直这么认为. 先说下概念:反射 Reflection ...
- Python学习入门基础教程(learning Python)--8.3 字典常用的方法函数介绍
本节的主要讨论内容是有关dict字典的一些常用的方法函数的使用和范例展示. 1. clear清除字典数据 语法结构如下: dict_obj.clear() 示例代码如下: dict1 = {'web' ...
- PHP(方法 函数 循环 和 数组 查找)
循环 和 数组 查找 顺序查找 二分法查找 冒泡排序 方法 函数 定义:一堆代码的集合叫做函数(满足条件下“一堆”) 语法,定义,调用,参数列表(形参,实参),返回值 两种方法: function 方 ...
随机推荐
- 模拟Push和Pop动作
//利用CATransition来作模拟 //模拟Push - (void)pushView:(UIView *)pushView inView:(UIView *)inView { CATransi ...
- 解决Cell重绘导致 重复的问题
IOS在Cell上的优化令人觉得底层框架的成熟,可是有些情形却会造成不必要的麻烦, 当使用了 UITableViewCell *cell = [tableView dequeueReusableCel ...
- Kafka简介及使用
一.Kafka概述 离线部分: Hadoop->离线计算(hdfs / mapreduce) yarn zookeeper->分布式协调(动物管理员) hive->数据仓库(离线计算 ...
- Mad Counting---LightOJ1148(好任性的过了)
题目链接:http://lightoj.com/volume_showproblem.php?problem=1148 已知有n个人,并且每个人都知道除自己之外还有m个人与自己支持的队一样,让我们求至 ...
- maven 之 web.xml 头设置错误问题
1.一般开发工具创建web.xml的时候会默认添加web.xml头,而有些插件(例如maven相关插件)默认添加的为 版本和你的开发工具Project facets(项目特性)中设置不同.那么就会导致 ...
- 通俗了解IaaS,PaaS,SaaS,看这里就对了(转)
[IT168 评论]云服务已经被大众所熟知,但对于刚接触云计算的朋友来说,仍然是云里雾里的绕着,今天小编就为你解读一下云计算的几种服务模式,IaaS,PaaS,SaaS到底是什么…区别有哪些? 字正腔 ...
- ViewFlipper
main.xml <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xml ...
- Lucene.Net 3.0.3如何从TokenStream中获取token对象
Lucene.Net最高版本为3.0.3,并且apache已经不再提供Lucene.Net的更新,没仔细研究过Lucene.Net的所有版本,Lucene.Net3.0.3遍历TokenStream获 ...
- SQL优化,解决系统运行效率瓶颈
http://www.cnblogs.com/SameZhao/p/4737725.html
- 巨坑:jqgrid竟然取不到编辑模式下input的值
今天遇到最奇葩的问题,竟然取不到input的值,感觉世界观都颠覆了.后来一搜资料,又是jqgrid框架搞的鬼,真搞不明白,开发框架就好好开发框架,留这么多坑有意思吗? jqgrid编辑模式下不要调用g ...