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 + ","))
}
posted @ 2016-05-13 10:32  lj72808up  阅读(127)  评论(0编辑  收藏  举报