• Scala基础:闭包、柯里化、隐式转换和隐式参数


    闭包,和js中的闭包一样,返回值依赖于声明在函数外部的一个或多个变量,那么这个函数就是闭包函数。

        val i: Int = 20
        //函数func的方法体中使用了在func外部定义的变量 那func就是个闭包函数
        val func = (x: Int) => x + i

    柯里化(Currying)指的是把原来接受多个参数的函数变换成接受一个参数的函数过程,并且返回接受余下的参数且返回结果为一个新函数的技术。柯里化并不是scala特有的,js中也有。

    package com.zy.scala
    
    object CurryingDemo {
      def main(args: Array[String]): Unit = {
    
        //原本的方法
        def m(x: Int, y: Int) = x + y
    
    
        //第一种柯里化
        def first(x: Int) = (y: Int) => x + y
    
        val second = first(1)
        val result: Int = second(2)
        println(result)
    
        //第二种柯里化
        def curriedSum(x: Int)(y: Int) = x + y
    
        val sum: Int = curriedSum(1)(2)
        println(sum)
    
      }
    }
    Scala 提供的隐式转换和隐式参数功能,是非常有特色的功能。是 Java 等编程语言所没有的功能。它可以允许你手动指定,将某种类型的对象转换成其他类型的对象或者是给一个类增加方法。通过这些功能,
    可以实现非常强大、特殊的功能。 Scala 的隐式转换,其实最核心的就是定义隐式转换方法,即 implicit conversion function。定义的隐式转换方法,只要在编写的程序内引入,就会被Scala 自动使用。Scala 会根据隐式转换方法的签名,
    在程序中使用到隐式转换方法接收的参数类型定义的对象时,会自动将其传入隐式转换方法,转换为另外一种类型的对象并返回。这就是“隐式转换”。其中所有的隐式值和隐式方法必须放到 object 中。 然而使用 Scala 的隐式转换是有一定的限制的,总结如下:   implicit 关键字只能用来修饰方法、变量(参数)。   隐式转换的方法在当前范围内才有效。如果隐式转换不在当前范围内定义(比如定义在另一个类中或包含在某个对象中),那么必须通过
    import 语句将其导。 所谓的隐式参数,指的是在函数或者方法中,定义一个用 implicit 修饰的参数,此时 Scala 会尝试找到一个指定类型的,用 implicit 修饰的参数,即隐式值,并注入参数。 Scala 会在两个范围内查找:   当前作用域内可见的 val 或 var 定义的隐式变量;   一种是隐式参数类型的伴生对象内的隐式值;

    隐式参数案例

    package com.zy.scala
    
    object Company {
      //在 object 中定义隐式值 注意:同一类型的隐式值只允许出现一次,否则会报错
      implicit val aaa = "zhangsan"
      implicit val bbb = 10000.00
    }
    
    class Boss {
      //注意参数匹配的类型 它需要的是 String 类型的隐式值
      def callName()(implicit name: String): String = {
        name + " is coming !"
      }
    
      //定义一个用 implicit 修饰的参数
      //注意参数匹配的类型 它需要的是 Double 类型的隐式值
      def getMoney()(implicit money: Double): String = {
        " 当月薪水:" + money
      }
    }
    
    object Boss extends App {
      //使用 import 导入定义好的隐式值,注意:必须先加载否则会报错
      import Company._
    
      val boss = new Boss
      println(boss.callName() + boss.getMoney())
    }

    隐式转换

    package com.zy.scala
    
    import java.io.File
    import scala.io.Source
    
    object MyPredef {
      //定义隐式转换方法
      implicit def file2RichFile(file: File) = new RichFile(file)
    }
    
    class RichFile(val f: File) {
      def read() = Source.fromFile(f).mkString
    }
    
    object RichFile {
      def main(args: Array[String]) {
        val f = new File("E://words.txt")
        //使用 import 导入隐式转换方法
        import MyPredef._
        //通过隐式转换,让 File 类具备了 RichFile 类中的方法
        val content = f.read()
        println(content)
      }
    }
    package com.zy.scala
    
    class Man(val name: String)
    
    class SuperMan(val name: String) {
      def heat = print("超人打怪兽")
    }
    
    object SuperMan {
      //隐式转换方法
      implicit def man2SuperMan(man: Man) = new SuperMan(man.name)
    
      def main(args: Array[String]) {
        val hero = new Man("hero")
        //Man 具备了 SuperMan 的方法
        hero.heat
      }
    }
    package com.zy.scala
    
    class A(c: C) {
      def readBook(): Unit = {
        println("A 说:好书好书...")
      }
    }
    
    class B(c: C) {
      def readBook(): Unit = {
        println("B 说:看不懂...")
      }
    
      def writeBook(): Unit = {
        println("B 说:不会写...")
      }
    }
    
    class C
    
    object AB {
      //创建一个类的 2 个类的隐式转换
      implicit def C2A(c: C) = new A(c)
    
      implicit def C2B(c: C) = new B(c)
    }
    
    object B {
      def main(args: Array[String]) {
        //导包
        //1. import AB._ 会将 AB 类下的所有隐式转换导进来
        //2. import AB._C2A 只导入 C 类到 A 类的的隐式转换方法
        //3. import AB._C2B 只导入 C 类到 B 类的的隐式转换方法
        import AB._
        val c = new C
        //由于 A 类与 B 类中都有 readBook(),只能导入其中一个,否则调用共同方法时代码报错
        //c.readBook()
        //C 类可以执行 B 类中的 writeBook()
        c.writeBook()
      }
    }
  • 相关阅读:
    获取成本
    销售订单跟踪成本
    装机
    这就是用战术上的勤奋掩盖战略上的懒惰
    CPA-计划(参考)
    大帝名言
    BZOJ 2100: [Usaco2010 Dec]Apple Delivery spfa
    BZOJ 2834: 回家的路 Dijkstra
    BZOJ 4070: [Apio2015]雅加达的摩天楼 根号分治+spfa
    BZOJ 4152: [AMPPZ2014]The Captain Dijkstra+贪心
  • 原文地址:https://www.cnblogs.com/blazeZzz/p/9806684.html
Copyright © 2020-2023  润新知