zoukankan      html  css  js  c++  java
  • ScalaTour-1.基础

    import java.io.{BufferedReader, File, FileInputStream, InputStreamReader}
    import java.util
    import java.util.Scanner
    
    /**
      * Created by thinkpad on 2016/5/9.
      */
    object TestHigherKinded {
    
    }
    
    
    //借贷模式:函数作为参数传递
    object funAsParam{
      def opFile(f:File,fun:BufferedReader=>Unit)= {
        val reader = new BufferedReader(new InputStreamReader(new FileInputStream(f)))
        try{
          fun(reader)
        }finally {
          reader.close()
        }
      }
      opFile(new File("d://123.txt"),(reader:BufferedReader) =>println(reader.readLine()))
    }
    
    
    /** scala的函数偏向于理解为数学代数式。因此,函数的参数列表分为值传递和参数名传递
      * 1)值传递:如果参数以计算式出现(2+3),则计算值后传入函数
      * 2)参数名传递:如果参数以计算式出现,直接带入函数中。
      *
      * 参数名传递的写法:定义函数的参数形式:参数:=>参数类型
      */
    object obj2 {
      /**例子1*/
      def add1(a: Int, b: Int): Int = a + b
      def add2(a: Int, b: => Int): Int = a + b
    
      println(add1(1, 2 + 3)) //值传递:先计算2+3=5,在计算add1(1,5)
      println(add2(1, 2 + 3))  //参数名传递:add2(1,2+3) = 1+2+3
    
      /**例子2*/
      val logEnable = false
      def log1(msg:String)={if(logEnable) println(msg)}       // 值传递
      def log2(msg: =>String)={if(logEnable) println(msg)}    // 参数名传递
    
      //log1("hello"+1/0)     1/0报错,函数的值传递先解析参数值
      log2("hello"+1/0)      // 参数名传递不解析参数值,原样带入函数后,logEnable为false,不用计算1/0
    }
    
    /** 鸭子类型:
      *     如果一只动物,走起来像鸭子或者叫起来像鸭子,就可以把它当作鸭子。
      *     也就是说,如果它含有我想要的功能,那么我可以把它当作真的来对待。
      *  鸭子类型的写法:
      *     def 需要的函数名:返回值类型
      * {def close():Unit}生命了鸭子类型的行为(带有close方法的对象)
      * closeable:{def close():Unit}  : 函数别名:鸭子类型
      * op:{def close():Unit} => Unit : 函数别名:鸭子类型=> 返回值类型
      */
    class obj3{
      def withClose(closeable:{def close():Unit},op:{def close():Unit} => Unit)={
        try{
          op(closeable)
        }finally {
          closeable.close()
        }
      }
    
      class Connection{
        def close():Unit = println("conn is closed")
      }
    
      val conn = new Connection
      withClose(conn,conn=>println("something is done"))   // “=>”在scala中用于匿名函数。匿名函数作为参数时,=>左侧是参数列表,右侧是返回值。调用带匿名函数为参数的函数时,=>左侧为参数,右侧为函数体
      /*
        something is done
        conn is closed
      */
    }
    
    
    /** 柯里化
      * (1) scala认为,参数列表为1的函数时最舒服的函数(类比一元函数),因此,柯里化来实现把多参函数转变为1参函数
      * (2) 柯里化的一般过程:
      *     add(x:Int,y:Int)=x+y     ====>    add(x:Int)(y:Int)=x+y    ====>    add(x:Int)=(y:Int)=>x+y
      *                    括号分开形成2个参数列表参数        参数列表间加=,函数体前面的=变为=>
      * */
    object obj4 extends App{
      // 把上面的鸭子函数柯里化
      def withClose(closeable:{def close():Unit})(op:{def close():Unit} =>Unit)={
        try{op(closeable)}finally {closeable.close()}
      }
      class Connection{
        def close():Unit = println("conn is closed")
      }
      val conn = new Connection
      withClose(conn)(conn=>println("something is done"))   // “=>”在scala中用于匿名函数。匿名函数作为参数时,=>左侧是参数列表,右侧是返回值。调用带匿名函数为参数的函数时,=>左侧为参数,右侧为函数体
    
    }
    
    //泛型+鸭子类型+柯里化定义函数 , 简化上面的写法
    object obj5 extends App{
      def withClose[A <: {def close():Unit},B](closeable:A)(f:A=>B) : B={  //简化的定义
        try{f(closeable)}finally {closeable.close()}
      }
      class Connection{
        def close():Unit = println("conn is closed")
      }
      val conn = new Connection
      val res = withClose(conn)(conn=>{println("something is done");12345})
      print(res.isInstanceOf[Int])  //true
    }
    
    //trait:有函数体的interface
    trait Foreachable[A]{
      def iterator: java.util.Iterator[A]
      def foreach(f:A=>Unit):Unit={
        val iter = iterator
        while(iter.hasNext)
          f(iter.next)
      }
    }
    object obj6 extends App{
      val list = new util.ArrayList[Int] with Foreachable[Int]
      list.add(1)
      list.add(2)
      list.foreach(x => print(x + ","))
    }
    
  • 相关阅读:
    linux下查看nginx,apache,mysql,php的编译参数
    Nginx重大漏洞,文件类型错误解析
    用C语言编写PHP扩展1(转)
    数字证书中keytool命令使用说明
    Nginx 日志文件切割
    推荐12款精心设计网站设计PSD模板
    分享9个最棒的代码片段资源网站
    强大的独立日期选择器(date picker)插件 Kalendae
    分享一个HTML5的drag and drop API实现的图片拖拽分组效果
    你真的很了解HTML标签吗? 试试这个超异类的HTML标签小测验吧!
  • 原文地址:https://www.cnblogs.com/72808ljup/p/5488506.html
Copyright © 2011-2022 走看看