【Scala 2.11.8 入门 】Scala入门②函数式编程 2019_12_3

函数式编程

函数基础

一切皆函数(真),一切皆对象(真)
【PS:而不像Java 还有为了舔C++遗留的基本数据类型】

//基础语法:
def    sum (x: Int , y: Int) : Int           =   { x + y }
关键字 函数签名                 函数返回值类型       函数体

//函数 || 方法:
定义在 class 类体中的 函数 称为 方法【当然二者结构都可是一样的】{
定义在 方法 中的 函数 称为 函数
注1:Scala语言可以在任何的语法结构中声明任何的语法
注2:函数没有重载和重写的概念;方法可以进行重载和重写
注3:Scala中函数可以嵌套定义
函数嵌套
object TestFunction {
    def main(args: Array[String]): Unit = {
        //嵌套 定义函数
        def test1() ={
            def test2(name:String):Unit={
                println("函数可以嵌套定义")
            }
            test2("abc")
        }
        test1() // 函数可以嵌套定义
    }
}
函数参数
函数参数:
(1)可变参数
(2)如果参数列表中存在多个参数,那么可变参数放置在最后
(3)参数默认值,一般将有默认值的参数放置在参数列表的后面
(4)带名参数,如果有默认值参数不在参数列表的最后,可以在调用函数的时候使用 命名参数

//1.可变参数 Type*
def test( s : String* ): Unit = {
    println(s)
}

//2.多参数,可变参数放置最后
def test2( id: Int, s: String* ): Unit = {
    println(s)
}

//3.参数默认值
def test3( name : String, age : Int = 30 ): Unit = {
    println(s"$name, $age")
}
def test4( age : Int = 30, name : String ): Unit = {
    println(s"$name, $age")
}

//(4)带名参数
test4(name="ximenqing") //ximengqing,30
函数至简原则
(1)return 可以省略,Scala会使用函数体的最后一行代码作为返回值
(2){} 花括号可以省略,如果函数体只有一行代码,
(3): Type 参数类型/函数返回值类型 如果能够推断出来那么可以省略
(4)= 等号可以省略,如果函数期望是无返回值 Unit类型,
(5)() 小括号可以省略,如果函数没有显式声明参数列表(),那么调用时小括号必须省略
(6)def + 函数名 可以省略,如果不关心名称,只关心函数内部的逻辑处理
(7)如果函数无参,但是声明了参数列表,那么调用时,小括号,可加可不加
(8)如果函数体有return关键字,则不能省略声明函数返回值类型,必须指定
(9)如果函数返回值显式声明 Unit类型,那么即使函数体中使用return关键字也不起作用

函数高级

关于,Scala 函数Function 与方法Method 的区别:
如果定义在类体中,使用def 关键字,我们通常叫它为 方法
如果定义在方法中,通常不使用 def 关键字,我们通常加它为 函数

高阶函数
函数作为值传递 val a = foo()
函数作为整体传递 val b = foo _
函数作为参数传递 (f: U => V)
函数作为函数返回值 { f2_ }

一切皆函数
object TestFuncHigh {
  def main(args:Array[String]): Unit ={
    //1.将函数返回值 传递给 var/val
    println("--- 函数返回值被传递 ---")
    val fv = fValue(1) // 简写==> val fv = fValue()
    println(fv)

    //2.1将函数整体 传递给 var/val _代表参数/返回值类型推断
    println("--- 函数整体被传递 ---")
    val ff = fValue _
    println(ff(2))

    //2.2明确var/val 函数参数&返回值类型,则可以不使用 _
    var ff2:(Int)=>Int = fValue
    println(ff2(3))

    //3.将嵌套定义的内层 函数整体 作为外层 函数返回值 传递给变量(函数整体传递的一种)
    println("--- 内层函数整体作为外层函数返回值被传递 ---")
    println("单层调用")
    val innerF = f1()
    println("单层调用")
    innerF()
    println("双层调用")
    f1()()

    //4.函数作为形式参数被定义 及 传递调用
    println("--- 函数作为形式参数被定义及传递调用 ---")
    val fP = fParam(fValue)
    println(fP)

  }

  def fValue(a: Int): Int ={
    println("fValue")
    a
  }

  def f1 ()={
    println("f1")
    def f2 ()={
      println("f2")
    }
    f2 _
  }
    
  def m1(a:Int) = {
    def m2(b:Int)= {
      def m3(m4:(Int,Int)=>Int)= {
        m4(a,b)
      }
      m3 _
    }
    m2 _
  }

  //完整函数定义:def 函数签名 : 函数返回值 = {函数体}
  //函数作为形式参数声明:参数列表 (形参函数名: 参数1,参数2,... => 形参函数返回值类型)
  //注:形参函数写在 参数列表 == 小括号()里,也就没办法写完整函数定义,一切从简
  def fParam(f: Int => Int): Int = {
    //调用传入参数:函数f
    f(4)
  }
}
匿名函数
匿名函数 == 不关心函数名称 / 不二次调用的函数。如 形参函数
格式:(参数列表)=>{函数体}
传递匿名函数简化原则:
(1)参数类型 :Type 省略,会根据形参进行自动的推导
(2)只有一个参数,则圆括号 () 可以省略;其他情况:没有参数和参数超过1的永远不能省略圆括号。
(3)函数体只有一行,则大括号 {} 也可以省略
(4)参数只出现一次,则参数省略且后面参数调用可用"_"代替

object TestAnonymity {
  def main(args: Array[String]): Unit = {
    //0.传入 实参 函数f1
    val arr0 = f0(Array(1, 2, 3, 4), f1)
    println(arr0.mkString(","))

    //1.传入 一个实参 匿名函数
    val arr1 = f0(Array(1, 2, 3, 4), _ + 1)
    println(arr1.mkString(","))

    /**
     * val arr1 = f0(Array(1,2,3,4),(ele:Int)=>{ele+1})
     * val arr2 = f0(Array(1,2,3,4),(ele)=>{ele+1})
     * val arr3 = f0(Array(1,2,3,4),ele=>{ele+1})
     * val arr4 = f0(Array(1,2,3,4),ele=>ele+1)
     * val arr5 = f0(Array(1,2,3,4),_+1)
     */

    //2.传入 两个实参 匿名函数
    val arr2 = f2(Array(1, 2, 3, 4), _ + _)
    println(arr2.mkString(","))
  }

  def f0(arr: Array[Int], op: Int => Int) = {
    for (elem <- arr) yield op(elem)
  }

  def f2(arr: Array[Int], op: (Int, Int) => Int) = {
    for (elem <- arr) yield op(elem, 1)
  }

  def f1(m1: Int): Int = {
    m1 + 1
  }
}
闭包&函数柯里化
闭包 == {外部函数的局部变量(外部函数已弹栈的情况下)存活 + 内部函数} ==> 新的对象 == 同一生命周期
函数柯里化 == 一个参数列表 转换为 多个参数列表 && 嵌套函数(闭包)的声明简化(可配合代码块传递)

object TestBBFunction {
  def main(args: Array[String]): Unit = {
    var a = 10

    //非函数式嵌套调用:
    //特点:在最内层调用未完成时,外层调用的方法并不弹栈
    //     以达到外层局部变量共享给内部调用函数,当外部调用的方法弹栈后,其局部变量也弹栈/释放
    TraditionM1(a)

    //函数式嵌套调用
    //特点:外层方法执行完毕后,方法出栈,而其仍被内层函数使用的局部变量不弹栈
    //     与内层函数组成一个共生命周期的环境/共同体/新对象【形成=>官方·闭包】
    val b = f1(a)()
    //多次执行,只执行()()()第三层嵌套函数,其所需的第一层方法的局部变量仍然留存。
    b() //10
    b() //10

    //柯里化,简化闭包函数(嵌套函数)调用
    klh(1)("abc")
  }

  /**
   * 传统方法的链式调用,缺点:大量嵌套方法压栈,栈空间不足
   * 优点:层次分明,易于理解
   * @param b 共享给m2,m3的参数
   */
  def TraditionM1(b: Int): Unit = {
    m2(b)
  }

  def m2(c: Int): Unit = {
    m3(c)
  }

  def m3(d: Int): Unit = {
    println(d)
  }

  /**
   * 1.嵌套的内部方法,可共享可能已被方法栈弹出的外部方法的局部变量 ==> 闭包
   * 2.定义完f2,f3,需要将这些方法作为方法返回值返回
   * 3.方法的嵌套调用,优点:执行完的方法直接弹栈,但其嵌套范围内仍被引用的局部变量不会弹栈,
   *   也就是:解决了栈空间被嵌套方法占用问题,且弹栈方法的局部变量的生命周期被延长同内部嵌套函数
   *   也就是:嵌套外层的局部变量与其内部嵌套函数形成一个闭合共存空间 = 对象
   * @param b
   */
  def f1(b: Int)= {
    def f2()= {
      def f3()= {
        println(b)
      }
      f3 _
    }
    f2 _
  }

  /**
   * 柯里化简化多层方法嵌套
   * 注:这样写,会将第一层方法逻辑省略,但仍可通过——传递代码块的方式
   *    在最内层方法中加入外层函数逻辑
   *    
   * def myWhile(condition: => Boolean)(op: => Unit): Unit = {
   *   //1.如果满足循环条件,执行循环体op
   *   if (condition) {
   *     op
   *     myWhile(condition)(op)
   *   }
   * }
   *
   * @param a 第一层方法
   * @param s 第二层方法
   */
  def klh(a:Int)(s:String): Unit ={
    println(a)
  }
}
控制抽象
函数参数传递:3种情况
1.值传递
2.函数传递
3.代码块传递 ==> 控制抽象

object TestWhileFunction {
  def main(args: Array[String]): Unit = {
    //0.定义一个匿名函数,作为参数化函数
    val block = (res: Int) => {
      println("--- block ---")
      res
    }
    //1.传递值(block函数返回值)
    foo(block(10))
    /*
      --- block ---
      10
      10
     */

    //2.传递代码块
    foo2(block(10))
    /*
      --- block ---
      10
      --- block ---
      10
     */

    //3.传递函数
    foo3(block)

    //4.控制抽象实例:myWhile 函数,传入两个参数
    var i = 1
    myWhile(i <= 10) {
      println(i)
      i += 1
    }
  }

  //传递值
  //格式:(参数名: 参数类型)
  def foo(a: Int): Unit = {
    println(a)
    println(a)
  }

  //传递代码块
  //格式:(参数化代码块名: => 代码块返回值类型)
  def foo2(a: => Int) {
    println(a)
    println(a)
  }

  //传递函数
  //格式:(参数化函数名: 参数化函数参数类型 => 参数化函数返回值类型)
  def foo3(f: Int => Int): Unit = {
    println(f(10))
    println(f(10))
  }

  /**
   * 注意:condition 不能为变量参数(值传递),而应是代码块参数(可动态变化)
   *
   * @param condition 条件代码块
   * @param op        执行代码块
   */
  def myWhile(condition: => Boolean)(op: => Unit) {
    //1.如果满足循环条件,执行循环体op
    if (condition) {
      op
      myWhile(condition)(op)
    }
  }
}
递归
object TestDGFunction {
  def main(args: Array[String]): Unit = {
    println(jc(5))
    println(addFunction(20, 2))
  }

  /**
   * 阶乘方法
   * @param n n的阶乘
   * @return 递归式
   */
  def jc(n:Int):Int={
    //1.收敛条件:注意使用return结束整个函数
    if( n == 1)
      return 1
    //2.处理
    //3.return 递归
    n*jc(n-1)
  }
    
  /**
   * 位运算,实现的加法器
   * @param a 加数1 / 无进位和数
   * @param b 加数2 / 进位
   * @return 迭代式
   */
  def addFunction(a:Int,b:Int): Int ={
    if (b==0)
      return a
    addFunction(a^b,(a&b)<<1)
  }
}
惰性执行
object TestLazyFunction {
  def main(args: Array[String]): Unit = {
    //惰性关键字:只被允许定义在 val 不变量前
    //当函数返回值被声明为lazy时,函数的执行将被推迟,直到我们首次对此取值,该函数才会执行
    lazy val res = sum(10,10)
    println("_______")
    println("res="+res)
  }

  def sum (n1:Int,n2:Int):Int = {
    println("--sum--")
    n1 + n2
  }
}

1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
应用背景为变电站电力巡检,基于YOLO v4算法模型对常见电力巡检目标进行检测,并充分利用Ascend310提供的DVPP等硬件支持能力来完成流媒体的传输、处理等任务,并对系统性能做出一定的优化。.zip深度学习是机器学习的一个子领域,它基于人工神经网络的研究,特别是利用多层次的神经网络来进行学习和模式识别。深度学习模型能够学习数据的高层次特征,这些特征对于图像和语音识别、自然语言处理、医学图像分析等应用至关重要。以下是深度学习的一些关键概念和组成部分: 1. **神经网络(Neural Networks)**:深度学习的基础是人工神经网络,它是由多个层组成的网络结构,包括输入层、隐藏层和输出层。每个层由多个神经元组成,神经元之间通过权重连接。 2. **前馈神经网络(Feedforward Neural Networks)**:这是最常见的神经网络类型,信息从输入层流向隐藏层,最终到达输出层。 3. **卷积神经网络(Convolutional Neural Networks, CNNs)**:这种网络特别适合处理具有网格结构的数据,如图像。它们使用卷积层来提取图像的特征。 4. **循环神经网络(Recurrent Neural Networks, RNNs)**:这种网络能够处理序列数据,如时间序列或自然语言,因为它们具有记忆功能,能够捕捉数据中的时间依赖性。 5. **长短期记忆网络(Long Short-Term Memory, LSTM)**:LSTM 是一种特殊的 RNN,它能够学习长期依赖关系,非常适合复杂的序列预测任务。 6. **生成对抗网络(Generative Adversarial Networks, GANs)**:由两个网络组成,一个生成器和一个判别器,它们相互竞争,生成器生成数据,判别器评估数据的真实性。 7. **深度学习框架**:如 TensorFlow、Keras、PyTorch 等,这些框架提供了构建、训练和部署深度学习模型的工具和库。 8. **激活函数(Activation Functions)**:如 ReLU、Sigmoid、Tanh 等,它们在神经网络中用于添加非线性,使得网络能够学习复杂的函数。 9. **损失函数(Loss Functions)**:用于评估模型的预测与真实值之间的差异,常见的损失函数包括均方误差(MSE)、交叉熵(Cross-Entropy)等。 10. **优化算法(Optimization Algorithms)**:如梯度下降(Gradient Descent)、随机梯度下降(SGD)、Adam 等,用于更新网络权重,以最小化损失函数。 11. **正则化(Regularization)**:技术如 Dropout、L1/L2 正则化等,用于防止模型过拟合。 12. **迁移学习(Transfer Learning)**:利用在一个任务上训练好的模型来提高另一个相关任务的性能。 深度学习在许多领域都取得了显著的成就,但它也面临着一些挑战,如对大量数据的依赖、模型的解释性差、计算资源消耗大等。研究人员正在不断探索新的方法来解决这些问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值