scala函数进阶篇
1、求值策略
scala里有两种求值策略
Call By Value -先对函数实参求值,在函数体中用这个求出的参数值。
Call By Name -先不对函数实参求值,而是函数实参每次在函数体内被用到时都会求值。
scala通常使用Call By Value
如果函数形参类型以 =>开头,那么就是在使用Call By Name
def foo(x : Int)= x //Call By Value
def foo(x : => Int)= x //Call By Name
def loop():Int = loop //递归函数 //> loop: ()Int
def bar(x : Int,y : =>Int) =1 //> bar: (x: Int, y: => Int)Int
bar(1,loop) //> res3: Int = 1
//bar(loop,1) //会死循环
2、高阶函数
用函数作为形参或带返回值的函数,称为高阶函数
def operate(f: (Int,Int) => Int)={
f(4,4)
}//形参传入的是一个函数
def greeting()= (name: String) =>{"hello "+name}//返回一个匿名函数
3、匿名函数
匿名函数就是函数常量,也称为函数文字量
在scala里,匿名函数的定义格式为(形参列表)=>{函数体}
4、柯理化
柯理化函数把具有多个参数的函数转换为一条函数链,每个节点上是单一参数
def add(x: Int,y: Int)= x + y //常规函数写法
def add(x: Int)(y: Int) = x + y //scala中柯理化的语法
5、递归函数
在函数式编程中是实现循环的一种技术。
缺陷:递归的层数越深,栈就越多。
6、尾递归函数
尾递归函数中所有递归形式的调用都出现在函数的末尾。
当编译器检测到一个函数调用的是尾递归的时候,它就覆盖当前的活动记录而不是在栈中去创建一个新的。
def factorial(n: Int):Int = {
if(n<=0) 1
else n*factorial(n)
}
@annotation.tailrec
def factorial(n: Int,m: Int):Int = {
if(n<=0) m
else factorial(n-1,m*n)
}
-----------下面是scala中常用函数的使用------------
val multiplier = (i: Int, m: Int) => i * m //> multiplier : (Int, Int) => Int = <function2>
def function1(n: Int): Int = {
multiplier.apply(n, 2) //等价于multiplier(n,2)
} //> function1: (n: Int)Int
function1(1) //> res4: Int = 2
def function2(m: (Int) => Int) = m //> function2: (m: Int => Int)Int => Int
def funint2(m: Int): Int = m //> funint2: (m: Int)Int
function2(funint2)(2) //> res5: Int = 2
def function3(f: (Int, Int) => Int) = f //> function3: (f: (Int, Int) => Int)(Int, Int) => Int
def funint3(m: Int,n: Int): Int= m*n //> funint3: (m: Int, n: Int)Int
function3(funint3)(2,3) //> res6: Int = 6
def greeting()= (name: String) => {"hello "+ name}
//> greeting: ()String => String
greeting()("xiaoming") //> res7: String = hello xiaoming
val function4 = (x: Int) => x + 1 //> function4 : Int => Int = <function1>
function4(4) //>res8: Int = 5
val function5 = (x:Int) => {
if(x > 1){
"x>1 and x=" +x
}else{
"x<1 and x = " +x
}
} //> function5 : Int => String = <function1>
function5(5) //> res9: String = x>1 and x=5
val function6 = (_ : Int) + ( _ :Int) //> function6 : (Int, Int) => Int = <function2>
function6(5,6) //> res10: Int = 11
def function7(a:Int, b:Int, c:Int) = a+b+c //> function7: (a: Int, b: Int, c: Int)Int
val function8 = function7 _ //> function8 : (Int, Int, Int) => Int = <function3>
function8(1,2,3) //> res11: Int = 6
def function9(args: Int*) = for (arg <- args) println(arg)
//> function9: (args: Int*)Unit
function9(1,2,3) //> 1
//| 2
//| 3
scala函数进阶篇的更多相关文章
- 第六篇:Python函数进阶篇
在了解完了 Python函数基础篇之后,本篇的存在其实是为了整合知识,由于该篇的知识是否杂乱,故大家可以通过点开点连接直接进入其详细介绍,该篇主要大致的介绍一下几个知识点: 一.Python的迭代器 ...
- Golang简单入门教程——函数进阶篇
本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是golang专题的第八篇,我们来聊聊golang当中的函数. 我们在之前的时候已经介绍过了函数的基本用法,知道了怎么样设计或者是定义一 ...
- Scala函数高级篇
一.匿名函数 没有名字的函数就是匿名函数,格式:(x:Int)=>{函数体} x:表示输入参数类型:Int:表示输入参数类型:函数体:表示具体代码逻辑 传递匿名函数至简原则: 参数的类型可以省略 ...
- Python之函数——进阶篇
嵌套函数 ---函数内部可以再次定义函数 ---函数若想执行,必须被调用 注意,下例中,执行结果为什么? age = 19 def func1(): print(age) def func2(): p ...
- Python—函数进阶篇
lambda表达式(匿名函数表达式) 作用:创建一个匿名函数对象.同def类似,但不提供函数名. 语法:lambda [形参1,形参2,...] : 表达式 语法说明 lambda 只是一个表达式,它 ...
- scala函数进阶与lazy的作用
内容如下. lazy修饰的变量可以延迟初始化,如下面所示,文件未必存在,file变量未必有内容.
- Scala进阶之路-Scala函数篇详解
Scala进阶之路-Scala函数篇详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.传值调用和传名调用 /* @author :yinzhengjie Blog:http: ...
- Node.js进阶篇-koa、钩子函数、websocket、嵌入式开发
代码地址如下:http://www.demodashi.com/demo/12932.html 一.简介 koa是由Express原班人马打造的,致力于成为一个更小.更富有表现力.更健壮的We ...
- labview从入门到出家5(进阶篇)--程序调试以及labview函数库的运用
跟了前面几章的操作流程,相信大家对labview有了一定的认识.其实只要了解了labview的编程思路,再熟悉地运用各个变量,函数以及属性,那么我们就可以打开labview的大门了.跟其他编程语言一样 ...
随机推荐
- 关于一个页面的tab切换整体页面刷新而tab标签处是同一个文件怎么做焦点的问题
解决方法,不能直接写点击效果就要在超链接中加一个参数,根据参数的值去给变焦点的效果,实现方法如下: <div class="vip_search"> ...
- Web应用程序开发的标准架构
- 基于jQuery左右滑动切换图片代码
分享一款基于jQuery左右滑动切换图片代码.这是一款基于jQuery实现的左右滑动切换焦点图代码.效果图如下: 在线预览 源码下载 实现的代码: <div class="v_ou ...
- MySQL数据类型和运算符
mysql支持多种数据类型,主要有下面三种: 数值数据类型 日期/时间类型 字符串类型 整数类型 不同数据类型有不同的取值范围,可存储的值的范围越大,则所需的存储空间也越大. 整数类型主要有: tin ...
- 获取touchstart,touchmove,touchend 坐标
简单说下如何用jQuery 和 js原生代码获取touchstart,touchmove,touchend 坐标值: jQuery 代码: $('#id').on('touchstart',funct ...
- SAX与DOM解析XML的区别
解析xml有四种方法:DOM,SAX,DOM4j,JDOM. 我们主要学了两种:DOM和SAX. DOM适于解析比较简单的XML而SAX则适于解析较复杂的XML文件.各有各的好. DO ...
- python + opencv: kalman 跟踪
之前博文中讲解过kalman滤波的原理和应用,这里用一个跟踪鼠标的例程来演示怎么在opencv里用自带的kalman函数进行目标跟踪,文章的内容对做图像跟踪有借鉴意义.文章主要是网络资源进行整理和简单 ...
- WPF查找子控件和父控件方法
一.查找某种类型的子控件,并返回一个List集合 public List<T> GetChildObjects<T>(DependencyObject obj, Type ty ...
- MFC 无边框窗体实现用鼠标拖动窗体边缘实现窗体大小变化
无边框窗体如何实现用鼠标拖动窗体边缘实现窗体大小变动呢?下面介绍一种方法,通过以下几个步骤即可实现: 1.实现WM_NCHITTEST消息,实现四条边框的模拟 2.实现WM_NCLBUTTONDOWN ...
- android boot.img unpack pack
每次编译boot.img都要花比较长的时间,有时候只是更改其中的配置文件. 如果能够将boot.img解压,更改之后再打包的话,就能节省时间. boot.img tools是别人写好的工具,能很好的解 ...