Scala学习(三)---函数式编程

2023-10-28

1.面向对象编程

Scala语言是一个完全面向对象的编程语言。万物皆是对象
对象的本质:对数据和行为的一个封装

2. 函数式编程是什么

在解决问题的时候,将问题分解成一个个的步骤,将每一个步骤进行封装(函数),通过调用这些封装好的步骤来解决问题。
Scala语言是一个完全函数式编程的语言。万物皆是函数。
函数的本质:函数可以当成一个值被传递。

3.函数定义

a.函数无参,无返回值

  def fun1(): Unit = {
    println("无返回值")
  }

b.无参,有返回值

    def fun2():String={
      "helloworld"
    }

c.有参,无返回值

      def fun3(name: String):Unit={
      println(s"你好,$name")
    }

d.有参,有返回值

    def fun4(name:String) :String={
      s"我是$name"
    }
    var str1=fun4("mao")
    println(str1)

e.多参,无返回值

    def fun5(name:String,age:Int):Unit={
      println(s"我是$name,今年$age 岁了")
    }

d.多参,有返回值

    def fun6(name:String,age:Int):String={
      s"我是$name,今年$age 岁了"
    }
    var str2=fun6("mao",18);
    println(str2)

4.函数参数的特殊用法

可变参数,在参数后加*

    def sayhi(names:String*):Unit={
      println(s"hi $names")
    }

    sayhi()
    sayhi("zhangsan")
    sayhi("lisi","zhangsan")

在这里插入图片描述

如果参数列表中存在多个参数,那么可变参数的位置一般放置在最后

    def sayhi(age:Int,names:String*):Unit={
      println(s"hi $names")
    }

参数默认值,一般将带有默认值的参数放置在参数列表的后面

	//设置参数默认值
    def sayhi(names:String="mao"):Unit={
      println(s"hi $names")
    }
   sayhi()
   //将带有默认值的参数放置在参数列表最后
     def sayhi(names:String,age:Int=31):Unit={
      println(s"hi $names,$age")
    }
   sayhi("mao")

带名参数
如果带有默认值的参数没有放置在参数列表的最后,name在调用函数的时候,需要使用带名参数来调用

   def sayhi(age:Int=31,names:String):Unit={
      println(s"hi $names,$age")
    }
   sayhi(names = "mao")

5.函数至简原则

return可以省略,scala会使用函数体的最后一行代码最为返回值
如果函数体只有一行代码,可以省略花括号
返回值类型如果能够推断出来,那么可以省略(:和返回值类型一起省略)
如果有return,则不能省略返回值类型,必须指定
如果函数明确声明unit,那么即使函数体中使用return关键字也不起作用
scala如果期望是无返回值类型,可以省略等号
如果函数式无参的,但是声明了参数列表,那么在调用的时候,小括号可加可不加
如果函数没有参数列表,那么小括号可以省略,调用时候小括号必须省略
如果不关心名称,只关心逻辑处理,那么函数名(def)可以省略

6.匿名函数

下面就是一个未化简的匿名函数的示例:

    val function1: (String, Int) => String = (name: String, age: Int) => age + name + "heihei"
    val str = function1("mao", 18)
    println(str)

在这里插入图片描述
真正的函数是这样的:

def function1(name:String,age:Int):String={
	age+name+"heihei"
}
val str = function1("mao", 18)
println(str)

6.1 匿名函数化简原则

参数的类型可以省略,会根据形参进行自动的推导

    //通过参数的类型推断返回值的类型
    val function2=(name:String)=>name+"heihei"
    //通过返回值的类型推断参数的类型
    val function3:String=>String= (name) => name+"heihei"

类型省略之后,发现只有一个参数,则圆括号可以省略,其他情况:没有参数和参数超过1的永远不能省略圆括号。

 val function3:String=>String= name=> name+"heihei"

匿名函数如果只有一行,则大括号也可以省略
如果参数只出现一次,则参数省略且后面参数也可以用_代替

val function4:(Int,Int)=>Int=2*_+4*_

7.高阶函数

7.1 函数可以作为值进行传递

  def sayHi(name:String) : String={
    println(s"hi $name")
    name
  }

  //此时不是作为值进行传递,而是将方法的返回值传递给了变量
  val mao:String=sayHi("mao")

  //此时才是将函数作为值传递
  val func1: String => String = sayHi _

7.2 函数可以作为参数进行传递

格式如下:
函数(函数名:(参数类型)=>返回值类型):返回值类型={}

//示例:
  def operXY(x: Int, y: Int, func: (Int, Int) => Int): Int = {
    func(x, y)
  }
	//调用函数,使用匿名函数作为参数值
  val countResult: Int = operXY(10, 20, (x: Int, y: Int) => x + y)//或者化简为val countResult: Int = operXY(10, 20,_+_)

  println(countResult)

运行结果:
在这里插入图片描述
通过scala语言的此特点,可以极大的简化Java语言手写MapReduce的过程

    def mapreduce(data:String,map: (String)=>Int,reduce:(Int)=>String): String = {
      //使用map读取数据
      val i = map(data)
      //走shuffle
      println("走shuffle流程")
      //对shuffle后的数据进行聚合
      val result:String=reduce(i)
      result
    }
    //调用
    mapreduce("hello world",(data:String)=>data.length,(data:Int)=>data+"reduce之后")

运行结果:
在这里插入图片描述

7.3 函数可以作为返回值进行传递

    //函数可以作为返回值进行传递
    def sumXY(x:Int)={
      def sumY(y:Int):Int={
        x+y
      }
      //将内部定义的函数作为返回值进行返回
      sumY _
    }

    //提供第一个累加的数
    val func=sumXY(10)
    //提供第二个累加的数
    val result = func(20)
    println(result)

运行结果:
在这里插入图片描述

7.4 柯里化写法

    //2.定于一个函数,传入三个参数c:char,s:String,i:Int
    //如果三个参数为('0',"",0),返回false,否则返回true
    def func1(c:Char):String=>(Int=>Boolean)={
      def func2(s:String):Int=>Boolean={
        def func3(i:Int):Boolean={
          (c!='0'||s!=""||i!=0)
        }
        //将func3作为返回值返回
        func3 _
      }
      //将func2作为返回值返回
      func2 _
    }

    val function:String=>Int=>Boolean = func1('1')
    val function1:Int=>Boolean = function("b")
    val bool:Boolean = function1(10)
    println(bool)

在这里插入图片描述
使用柯里化写法对其进行简化:

    //柯里化写法
    def function6(c:Char)(s:String)(i:Int):Boolean={
      (c!='0'||s!=""||i!=0)
    }
    //调用
    val bool1 = function6('1')("a")(1)
    println(bool1)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Scala学习(三)---函数式编程 的相关文章

  • java.lang.OutOfMemoryError:Scala 上超出了 GC 开销限制

    我是 Scala 开发人员 我在Routes它包含的文件1008行如果我添加另一行 则会抛出下面的错误 Uncaught error from thread sbt web scheduler 1 shutting down JVM sin
  • 为什么 Scala 选项的 foreach 比 get 更好?

    为什么使用foreach map flatMap等被认为比使用更好get对于 Scala 选项 如果我使用isEmpty我可以打电话get安全 好吧 这又回到了 告诉 不要问 考虑这两行 if opt isDefined println o
  • Scala API 2.10.*:Function2.and然后发生了什么?

    我正在阅读 Joshua Suereth 所著的 Scala in Depth 我购买这本书是为了了解作者的明确能力 我在第 3 页上 在出现一堆拼写错误和不连贯的格式之后 好吧 我已经开始容忍这些错误 我偶然发现了以下示例 该示例涉及解决
  • Scala 中并发混合的最佳实践.Map

    The ScalaDoc http www scala lang org api current index html scala collection mutable ConcurrentMap关于并发Map 是这样说的 已弃用 自版本
  • 如何在scala中运行时查找类参数数据类型

    import scala reflect runtime universe import scala reflect runtime universe def getType T TypeTag obj T typeOf T case cl
  • Scala 中的类型安全原语

    我希望在我的 Scala 代码中拥有类型安全的原语 子类 而不会受到装箱性能的影响 对于延迟非常低的应用程序 例如 这样的事情 class Timestamp extends Long class ProductId extends Lon
  • Scala Vector 折叠语法(/: 和 :\ 和 /:\)

    有人可以提供一些例子来说明如何 and http www scala lang org archives downloads distrib files nightly docs library scala collection immut
  • 包含一些 F[_] 的元组/hlist 上的通用变换/折叠/映射

    我最近问映射并减少 折叠 scalaz Validation 的 HList https stackoverflow com questions 26410100 并得到了关于如何转换固定大小的元组的一个很好的答案Va T 这是一个别名sc
  • 为什么 Vector[Option[Int]] 上的 flatMap 其映射器函数结果不是 Vector[Option[Int]] 有效?

    例如 Vector Some 1 Some 2 Some 3 None flatMap n gt n 产生一个Vector 1 2 3 而不是给出错误 正如我在其他语言中看到的那样 flatMap当你有一个产生嵌套的映射器函数时使用 所以我
  • Slick 3 交易

    我对 slick 3 文档描述事务的方式感到困惑 我有 2 个光滑的代码 如下所示 def doSomething DB withTransaction implicit session gt userDao doSomething add
  • 生成 k 个成对独立的哈希函数

    我正在尝试实施一个计数最小草图 http en wikipedia org wiki Count Min sketchScala中的算法 所以我需要生成k个成对独立的哈希函数 这是一个比我以前编写过的任何东西都低的级别 除了算法类之外 我对
  • 如何将Spark DataFrame插入Hive内表?

    以追加模式将 DF 插入 Hive 内部表的正确方法是什么 看来我们可以使用 saveAsTable 方法直接将 DF 写入 Hive 或将 DF 存储到临时表然后使用查询 df write mode append saveAsTable
  • 在sbt的build.sbt文件中添加模块依赖信息

    我在 IntelliJ 中有一个多模块项目 如该屏幕截图所示 contexProcessor 模块依赖于 contextSummary 模块 一旦我在项目结构中设置了依赖项 IntelliJ 就会处理所有事情 然而 当我跑步时sbt tes
  • 使用值类参数的 Mockito 存根方法失败并出现 NullPointerException

    使用类型化值类作为 ID 是 Scala 中的常见模式 然而 在存根以值类作为参数的方法时 Mockito 似乎遇到了问题 在下面的示例中 第一个具有实际值的存根工作得很好 但第二个使用参数匹配器的存根会抛出 NullPointerExce
  • 超时对“Future”进行排序

    我利用了TimeoutScheduler介绍于Scala Futures 内置超时 https stackoverflow com questions 16304471 scala futures built in timeout 但是 现
  • 从单个字符串创建 Spark DataFrame

    我正在尝试采用硬编码字符串并将其转换为 1 行 Spark DataFrame 具有单列类型StringType 这样 String fizz buzz 将得到一个 DataFrame 其 show 方法如下 fizz buzz 迄今为止我
  • 如何在不进行硬编码的情况下使用 Cake 模式进行依赖注入?

    我刚刚阅读并享受蛋糕图案文章 http jonasboner com real world scala dependency injection di 然而 在我看来 使用依赖项注入的关键原因之一是您可以改变 XML 文件或命令行参数所使用
  • mssql 的 UUID 疯狂

    我的数据库条目有一个 UUID 及其值 使用 Microsoft SQL Server Management Studio 提取 CDF86F27 AFF4 2E47 BABB 2F46B079E98B 将其加载到我的 Scala 应用程序
  • 在 Akka Actor 中使用 Future

    我刚刚开始学习 Scala 中的 Akka Actors 我的理解是 Actor 收到的消息会在 Actor 的邮箱中排队 并一次处理一个 通过一次处理一条消息 可以缓解并发问题 竞争条件 死锁 但是 如果 Actor 创建一个 futur
  • 将数组中的值提取到元组中

    有没有一种简单的方法可以将列表的值提取到 Scala 中的元组中 基本上是这样的 15 8 split map toInt mkTuple 15 8 或者我可以采取其他方式 val x y 15 8 split map toInt 如果你把

随机推荐

  • (休息几天)读曼昆之微观经济学——税收归宿

    当政府对某商品征税时 谁是税收的真正承担者 是买方还是卖方承担了税收 或者是买卖双方分摊了税收负担 如果是 决定税收分摊比例的因素是什么 政府规定税收在买卖双方中的分摊比例 比如本例中的镇长建议的 是否可行 这些问题的回答需要使用到一个叫作
  • 区块链技术在应用过程中的安全问题主要体现哪些方面?

    区块链技术在快速应用的同时 其安全隐患也不容忽视 中企通宝区块链技术研究负责人认为 区块链在应用过程中的安全问题主要体现在三个方面 一是区块链系统本身的安全问题 包括智能合约的安全漏洞以及区块链平台的安全漏洞问题 二是网络资产的基础安全问题
  • Vijava 学习笔记之 HostSystem(内存总大小、内存已使用容量和CPU个数)

    package com vmware util import com vmware vim25 mo ServiceInstance import java net URL Created by vixuan 008 on 2015 4 1
  • STM32读取RS485传感器数据,但接收到的数据开头总是多一个字节或少一个一字节,有人能告诉我哪里出问题了吗

    STM32读取RS485传感器数据 但接收到的数据开头总是多一个字节或少一个一字节 有人能告诉我哪里出问题了吗
  • windows server 2012 防火墙 安全策略 限制ip远程及访问mysql

    今天在服务器上设置安全策略 有个奇葩的设置试了很多次 仍然不太理解 但按照以下方法是起作用的 目标 开启防火墙 限制服务器A上的MySQL数据库只能通过B访问 实现 1 首先设置A上的入站规则 添加更改后远程端口可访问 然后开启防火墙 如果
  • uniapp表单数据为“多级结构”,如何做校验

    开发项目的时候使用uniapp的表单 表单数据为多级结构 也就是对象里面嵌套对象 如何做校验 其实针对 多级结构数据 可以使用 动态表单校验 给单个uni forms item添加rule 给name绑定数组形式 代码如下
  • 四大坐标系转换和相机标定以及结果评估

    四大坐标系转换和相机标定以及结果评估 四大坐标系 坐标系转换 相机标定 matlab和python 标定结果评估 相机成像过程涉及坐标变换 包含世界坐标系 Xw Yw Zw 相机坐标 Xc Yc Zc 平面坐标 x y 像素坐标 u v 一
  • spring cloud config 中的application.yml 和 bootstrap.yml

    bootstrap yml 在 application yml 之前加载 bootstrap yml可以理解成系统级别的一些参数配置 这些参数一般是不会变动的 一般使用bootstrap yml是由于有远程配置需要load到本地 一般它会包
  • 基于cubemx的stm32f103指纹模块(AS608)

    寒假这段时间自己做了个指纹锁玩 在这里写一下指纹模块的用法 一 测试 新到手的AS608模块 可以在软件中测试一下功能是否正常 在使用这个配套软件的时候 注意要搭配TTL转串口使用 连接电源线和串口线四根就可以了 注意在测试的时候 要找对C
  • OSPF矢量图及不规则区域设计理论

    任何一台路由器勾画出一个区域的连接 都是通过矢量图的方式来表示 在根据树型结构算法 来计算去往非直连网络的路径信息 路由在勾画连接只包含三个参数 两类节点和节点之间的链路 节点 路由器节点 stub节点 pc所在的网络 环回口连接的网络 网
  • 规则引擎调研报告

    背景 我们公司由于业务的极具扩大 每天经过系统的金额也达到了20亿美金左右 这个时候对资金的管控就不能像以前那样分散在不同的系统 由不同的部门负责了 所以说 我们成立了风控部门 必须成立了专门的研发团队负责风控需求 要开始做风控了 我受命去
  • JS 防抖与节流

    防抖与节流 1 防抖 debounce 1 1 定义 在连续的多次触发同一事件的情况下 给定一个固定的时间间隔 假设 300 ms 该时间间隔内若存在新的触发 则清除之前的定时器并重新计时 重新计时 300 ms 表现为在短时间多次触发同一
  • OnNotify与OnChildNotify以及CStatic的DrawItem实现源代码

    OnNotify是用于子控件向父窗口发送消息用的 该消息的接收对象是父窗口 OnChildNotify是子控件向父窗口发送消息后 父窗口反射消息给子窗口用的 该消息的接收对象是子窗口 如 CDialog上有一个CStatic 在CStati
  • Could not determine which ”make“ command to run. Check the ”make“ step in the build configuration.报错

    一般情况下 工具 gt 选项 gt 构建和运行 gt 构建套件 Kit 在编译器里选择一个合适的编译器即可 but 可能由于我下载了很多次qt 文件夹位置被我搞坏了 可以检查一下项目里的构建设置 构建目录里是否在红色部分构建目录下有所示文件
  • linux查询java进程的指令,查询内存的指令,查看JVM参数

    参看所有java进程占内存 CPU使用情况 top b n 1 grep java awk print PID 1 mem 6 CPU percent 9 mem percent 10 查看java中的进程 这个指令可以查到PID和包名字
  • 系统故障-asp.net环境有误

    外播要用电子分call系统 所以他们要安装电子分call系统 去了一看 他们的系统有些问题问题现象 1 所有的toolbar控件 所有的客户端都无法显示这个控件 但只有两个客户端可以显示 经分析是asp组件有问题 所以重新安装asp net
  • 在Vue中使用QRCode生成二维码

    首先安装依赖包 npm cnpm install save qrcode 下面是qrcode vue文件 在script标签导入qrcode import QRCode from qrcode 我一般是写在mounted里面 如果需要什么条
  • 解决springboot使用logback日志出现LOG_PATH_IS_UNDEFINED文件夹的问题

    application properties 加入以下配置 logback home logging path D logs esb producer logback xml
  • SQL server 数据类型转换

    在 SQL Server 中 CONVERT 和 PARSE 函数可以用于将一个数据值从一种数据类型转换为另一种数据类型 它们与 CAST 函数一样是 SQL Server 中常见的数据类型转换函数 CONVERT 函数 CONVERT 函
  • Scala学习(三)---函数式编程

    文章目录 1 面向对象编程 2 函数式编程是什么 3 函数定义 4 函数参数的特殊用法 5 函数至简原则 6 匿名函数 6 1 匿名函数化简原则 7 高阶函数 7 1 函数可以作为值进行传递 7 2 函数可以作为参数进行传递 7 3 函数可