Scala之函数式编程
目录
函数和方法的区别:
参数默认值:
函数至简原则---能省则省:
至简原则细节
匿名函数的化简:
匿名函数至简原则:
高阶函数:
高阶函数的三种用法:
(1)函数可以作为值进行传递
(2)函数可以作为参数进行传递**
匿名化简:
柯里化写法:
闭包:
递归:
优化递归:尾递归优化
控制抽象:
值调用:
名调用:
懒加载:
函数和方法的区别:
方法和函数的区别就是在位置上的不同
方法--是在类中表示(面向对象)-----伴生对象中的方法(相当于静态方法) 或者在伴生类中定义方法
写在其他位置的都是函数
函数是支持嵌套的但是并不支持函数的重载和重写(重载和重写是针对的类中的方法而言)
Scala中也有可变参数,不过与Java不同
def main(args: Array[String]): Unit = {def sayhi(name: String*): Unit={println(s"hi $name")}sayhi()sayhi("shdus")sayhi("sdsdsd","shdushd")}
执行结果
参数默认值:
(Java中不存在默认值 可通过重载实现)
def main(args: Array[String]): Unit = {def sayhi(name: String="zhangsan"): Unit={println(s"hi $name")}sayhi()sayhi("shdus")//sayhi("sdsdsd","shdushd")}
执行结果:
当想使用默认参数时,且有多个参数时 需要使用带名参数
def main(args: Array[String]): Unit = {def sayhi(name: String="zhangsan",age :Int): Unit={println(s"hi $name age is $age")}sayhi(age = 18)sayhi("shdus",18)//sayhi("sdsdsd","shdushd")}
执行结果:
函数至简原则---能省则省:
至简原则细节
特殊情况 return 不能省略:
//def sayhi2(name :String) :String ={if(name==null){return ""}println(s"Hi $name")name}
比如 传入参数为null 这个return 就不能省略 这里要作为程序的一个出口
如果省略 则会执行下边的语句 返回name
(4)如果有 return,则不能省略返回值类型,必须指定
因为每一行代码都是一个代码块 如果不写返回类型 就会返回默认最后一行代码 这时return name的返回值类型为nothing类型
def sayhi5(name :String):String={println(s"hi $name")return name}
val function: (String, Int) => String = (name: String, age: Int) => name + "的年龄是" + age
匿名函数的化简:
匿名函数至简原则:
可根据后边推到前面 也可根据前面推到后边 一般都是化简后边的
val function1 = (name: String, age: Int) => name + "的年龄是" + age//后推前val function2: (String, Int) => String = (name,age) => name + "的年龄是" + age
//前面推后边
val function3: (String, Int) => String = (name: String, age: Int) =>{println(name + "的年龄是" + age+"666")name + "的年龄是" + age}
val function5 :(Int,Int)=>Int //输入类型 输出类型= {2*_+4*_}
高阶函数:
高阶函数的三种用法:
(1)函数可以作为值进行传递
是将这个函数当作值进行传递
val function: String => String = sayHi _function("tangxiaocong")
(2)函数可以作为参数进行传递**
先构造一个抽象函数 再调用的时候 当作参数传递真正的逻辑
高阶函数接受一个或多个函数作为参数,并/或返回一个函数作为结果。
def operaXY(x:Int,y:Int,func:(Int,Int)=>Int):Int={func(x,y)}def sumXY(x:Int,y:Int): Int =x+yval i: Int = operaXY(10, 20, sumXY)println(i);
(3)柯里化函数:
详见下文
不化简的匿名:
def operaXY(x:Int,y:Int,func:(Int,Int)=>Int):Int={func(x,y)}val i: Int = operaXY(10, 20, (x:Int,y:Int)=>x-y)println(i);
匿名化简:
(1)化简类型
(2)化简xy使用_代替
def operaXY(x:Int,y:Int,func:(Int,Int)=>Int):Int={func(x,y)}val i: Int = operaXY(10, 20, _-_)println(i);
(3)函数可以作为函数返回值返回***
涉及到函数的一个嵌套,一级调用返回的是一个函数 二级调用返回值
def sumxy1(x:Int)={def sumy(y:Int): Int ={x+y}sumy _}val function1: Int => Int = sumxy1(10)println("歇一会")val i1: Int = function1(20)println(i1)
使用匿名函数进行化简
将等号后边的匿名函数作为返回值进行返回
def sumxy2(x: Int): Int => Int = (y: Int) => x + y // 将等号后边的匿名函数作为返回值进行返回val intToInt: Int => Int = sumxy2(58)val i3: Int = intToInt(23)println(i3)
再次对匿名函数进行化简:
这种化简就是过度化简,难懂,不建议
def sumxy3(x: Int): Int => Int = x + _
柯里化写法:
为了防止过度化简,作者引入了一个数学概念---柯里化的写法:
把多个形参的参数列表打散成一个形参的多个参数列表
def KlH(c:Char)(s:String)(i:Int)={c !='0' || s != "" || i !=0}println(KlH('0')("")(0))
闭包:
闭包:函数式编程的标配
def sumx(x:Int)={def sumy(y:Int):Int={x+y}sumy _}
上述采用的相当于是柯里化写法--先进行第一层调用 传入x再传递给内层函数 让x从变量变成常量,防止多次嵌套造成栈溢出
val function: Int => Int = sumx(23)val i: Int = function(34)println(i)
递归:
递归:嵌套调用自身的函数 递归其实是不如循环快的,因为递归还是会造成压栈
def jc(n: Int):Long ={
//递归:嵌套调用自身的函数if(n==1)1elsejc(n-1)*n}println(jc(5))
优化递归:尾递归优化
尾递归:最后递归调用函数的一行 只有自身的函数 没有其他值
实际尾递归是用到了闭包 递归没办法用闭包(闭包 把上一层的变量在本层变成常量,减少压栈次数----引入了res变量)(其实相当于定义一个变量当作累加器,来替代压栈)
def jc1(n: Int,res:Long=1):Long ={//递归:嵌套调用自身的函数if(n==1)reselsejc1(n-1,res*n)}
判断是否是尾递归,可以使用一个注解----@tailrec(不是尾递归会报错)
控制抽象:
函数定义有值调用和名调用(两种方式的传参方式不同)
值调用:
--将代码块的结果作为参数传入函数中,使用参数时,只带入结果
(值调用是指函数在调用时,先计算参数的值,然后再将这个值传递给函数。这意味着每个参数都只计算一次)
名调用:
--直接将整个代码块传入参数中,使用一次参数就会运行一次
(名调用是指函数在调用时,将参数的表达式作为代码块传递给函数。这意味着每次函数使用参数时都会重新计算它的值。)
//值调用def sayHi1(name:String):Unit={println("函数调用")println(s"$name hi")println(s"$name hi")}sayHi1({println("hello")"linhai"})println("==================================================")//名调用def sayHi2(name: => String):Unit={println("函数调用")println(s"$name hi")println(s"$name hi")}
sayHi2({println("hello")"linhai"
})
运行结果的对比:
懒加载:
其实懒加载相当于Linux中的sleep函数 会暂时性休息,当使用到惰性语句的时候才会运行
关键字---lazy 而且lazy只能用于val关键字上
def sumxy(x:Int,y:Int):Int={println("sumxy调用")x+y
}lazy val sum=sumxy(10,20)println("啦啊啦啦啦")println(sum)
运行结果:
自定义while循环:
def mywhile(b:Boolean)(op : => Unit):Unit={if (b){opmywhile(b)(op)}}
var i=0mywhile(i<5)({println(i)i +=1})
上述代码会陷入死循环 因为传入b(i<5)的时候是值调用 只传参一次 一直为真则一直++
改进 对b进行名调用
Scala之函数式编程相关推荐
- Scala的函数式编程
为什么80%的码农都做不了架构师?>>> Scala的函数式编程 昨天去一家公司面试,额,他们想招erlang的开发人员,然后我会点scala,都是函数式语言么.所以就让我过去 ...
- Scala入门系列(7)-Scala之函数式编程
基础 概念 函数式编程 函数式编程中的函数指的并不是编程语言中的函数(或方法),它指的是数学意义上的函数,即映射关系(如:y = f(x)),就是 y 和 x 的对应关系. 数学上对于函数的定义是这样 ...
- 3000门徒内部训练绝密视频(泄密版)第3课:Scala中函数式编程彻底精通及Spark源码阅读
Scala中函数式编程彻底精通及Spark源码阅读 函数可以不依赖于类,函数可以作为函数的参数,函数可以作为函数的返回值 =>表明对左面的参数进行右面的加工 函数赋值给变量需要在函数名后面加空格 ...
- scala与函数式编程——从范畴论看函数式编程
什么是范畴? 生活中我们经常说:我们讲的不是一个范畴里的东西!意思就是说两个人所讲的事物不具有任何关联,没有相关性.其实范畴Category就是指一群事物以及这些事物之间的所有关联关系,这些事物和这些 ...
- 2021年大数据常用语言Scala(二十一):函数式编程 遍历 foreach
目录 遍历 foreach 使用类型推断简化函数定义 使用下划线来简化函数定义 遍历 foreach 之前,学习过了使用for表达式来遍历集合.我们接下来将学习scala的函数式编程,使用fore ...
- 2021年大数据常用语言Scala(二十):函数式编程 介绍
目录 函数式编程 介绍 函数式编程的意义在哪? 函数式编程 介绍 我们将来使用Spark/Flink的大量业务代码都会使用到函数式编程.下面的这些操作是学习的重点. 现在我们将会逐渐接触函数式编程的方 ...
- Scala函数式编程(三) scala集合和函数
前情提要: scala函数式编程(二) scala基础语法介绍 scala函数式编程(二) scala基础语法介绍 前面已经稍微介绍了scala的常用语法以及面向对象的一些简要知识,这次是补充上一章的 ...
- Scala学习教程笔记二之函数式编程、Object对象、伴生对象、继承、Trait、
1:Scala之函数式编程学习笔记: 1:Scala函数式编程学习:1.1:Scala定义一个简单的类,包含field以及方法,创建类的对象,并且调用其方法:class User {private v ...
- Scala入门系列(十):函数式编程之集合操作
1. Scala的集合体系结构 Scala中的集合体系主要包括(结构跟Java相似): Iterable(所有集合trait的根trait) Seq(Range.ArrayBuffer.List等) ...
最新文章
- matlab实验8数据分析与多项式计算,hashidamatlab实验八数据处理与多项式计算.doc
- 使用scapy回放wireshark抓到的包
- Ext JS 5的声明式事件监听
- [JAVA]字符串单词倒转处理前面的空格
- 《学习》13权限管理
- Python环境搭建及PyCharm下载安装
- 台媒体:IBM PC将成特洛伊木马【ZZ】【另一个角度】
- 关于 Kubernetes中集群统一日志管理方案(Elasticsearch+Filebeat+Kibana+Metricbeat)搭建的一些笔记
- sql server收缩数据库日志
- var_threshold
- python爬取网站视频保存到本地
- 程序员的自我修养_之三_曾国藩与左宗棠
- Python四行代码实现的猜数字小游戏,基于thinker,带GUI界面
- matlab中图像显示函数
- 2012伦敦奥运会垃圾邮件大战提前上演
- 看看女程序媛们的自述
- 工作流process-designer图 未执行的用户示例出线高亮显示bug
- H264 profile 及帧类型介绍
- mysql可串行化读音,Oracle与MySQL中“可串行化”的对比测试
- 【对讲机的那点事】“驴途”不是“囧途”,安全出游请务必配备上对讲机!
热门文章
- 华硕FL5900U笔记本电脑重装win10专业版详细操作教程
- linux战争雷霆无法运行,《战争雷霆》Mac版下载及运行问题汇总
- 颜色转换助手RGB888-565
- 详解CAD软件2023功能更新-7个随附专业化工具组合
- TEK-DPO2024示波器使用手册
- vue 引入json地图_在vue2.x中使用echarts,地图或者theme引入js 文件,会有问题,地图的json文件重新注册可以...
- 如何修改sql服务器名,修改计算机名并更新sqlserver中存储的服务器名称
- JavaScript实现京东首页轮播图
- 【Android】制作一个简易的画板
- Intel汇编-无符号整数除法