ScalaTour-1.基础

时间:2021-04-06 23:40:06
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 + ","))
}