object A { //统一java数值型和引用型在scala是 Any var echo = (arg:Any)=> println(arg); //匿名方法赋值给变量的方法实际上产生了一个FunctionN对象,并产生了一个这个对象的apply()方法,方法的参数个数就是匿名函数的参数个数 val x = (arg:String)=>arg; //val a = Array.apply(1,2,3); val j = List(a:_*); //val k = Array.apply(a:_*);//no `: _*' annotation allowed here (such annotations are only allowed in arguments to *-parameters) val a = 1 to 100; //函数声明 在输入中指定类型,输出类型在函数定义中 val even = (x:Int)=> x % 2 == 0; //函数声明时将输入输出类型指定,然后后面直接定义函数体 val odd:Int=>Boolean = x => x % 2 == 1; val list =(a:Range,m:Int=>Boolean) => a.filter(m); val aa = list(a,even).mkString(","); val hasChar = (s:String,c:Char)=>s.exists((p:Char)=>p==c); def fab(x:Int,y:List[Int]):List[Int]= { if(x==0) return y.reverse; val a::b::rest = y; fab(x-1,a+b::y); } val u = fab(15,List(1,1)); val f = (p:Int)=> print(p+"\t"); //变长参数 def sum(nums:Int*):Int= { var x =0; nums.foreach(x+=_); return x; } //伴生对象的apply方法可以直接用类名调用 H(a,b,c); def apply(nums:Int*):Int= { var x =0; nums.foreach(x+=_); return x; } def main(args:Array[String]):Unit= { println(sum(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23)); val j = Array(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23); //将数组传入变长参数函数中的方法 println(sum(j:_*)); print(A(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23)); // val echo = (args:String*) => args.foreach(println);//error: ')' expected but identifier found. // def echo(arg:String) = println(arg); ok // val x = echo _; ok // var x = (arg:String)=>println(arg); ok var s = println(_:String); //val exex = (a:String=>(),b:String)=>a(b); String=>() is error val exex = (a:String=>Unit,b:String)=>a(b); exex(s,"hello"); /* val f = (p:Int)=> { val x = p+1; x; //这种写法只能不要 return 否则 执行 f 返回 () } */ def f(p:Int):Int = { val x = p+1; return x;//这种写法可以要 return 也可以不要 return } print(f(4)); } } object AB { type moudle = () => Unit; def x(p:moudle):Unit = { p(); println(); p(); } def main(args:Array[String]):Unit = { x(()=>print("hello")); } } object D { def sum(x:Int,y:Int,z:Int):Int = x+y+z; def main(args:Array[String]):Unit = { val t = sum _; // 将def定义的函数变成变量传递 val s = t(1,_:Int,_:Int); print(s(3,4)); } } object E { //这样效率高一些,因为反编译后发现直接转化为循环 def fac(x:Int,y:Int):Int = { if(y==1) return x; return fac(x*y,y-1) } def fac2(x:Int):Int = { if(x==1) return 1; return x*fac2(x-1); } def main(args:Array[String]):Unit = { println(fac(1,10)); println(fac2(10)); } } object W //几种定义函数的方法 { def main(args:Array[String]):Unit = { val add:(Int,Int)=>Int = (x,y) => x+y; //val 常量名称:(输出参数类型列表)=>返回类型 = (输入参数列表) => 函数定义 val add2 = (x:Int,y:Int) => x + y; //val 常量名称 = (输入参数和类型列表) => 函数定义; def add3(x:Int,y:Int):Int = x + y; // def 函数名称(输入参数和类型列表):返回类型 = 函数定义; // val x:Int=>Int = x => x+1; //直接写 x+1 是不对的 val x:Int=>Int = { case x => x+1;} } } object X { def main(args:Array[String]):Unit = { //这个地方如果没有 lazy 关键字 repeat 无法实现递归定义,或者放到函数外面变成一个 object 属性变量,也不会立即求值 lazy val repeat : Stream[Int] = 12 #:: repeat; //Stream 是懒加载的列表,换成 List 将出现死循环 val z = repeat take (3); z.foreach(println); } } object Y { def main(args:Array[String]):Unit = { // 这个地方如果没有 lazy 关键字 的话定义常量的同时就会求值,所以里面的递归定义将导致对一个未定义完的变量求值 // 或者将这个变量定义到 main 函数外面 变成一个 object 属性变量,也不会立即求值 // 还有就是这种递归函数用 def 直接定义函数会更简单明确 lazy val fact:Int=>Int= { case 0=>1; case n => n*fact(n-1); //或者没有递归的时候也可以不要 lazy 关键字 } print(fact(10)); } } object V { import scala.actors.Actor; import scala.actors.Actor._; def main(args:Array[String]):Unit = { //两个 actor 对话 val a = actor { react { case (msg:String,sender:Actor) => println(msg);sender ! msg + " too"; } } val b = actor { react { //给另外一个 actor 发送消息 同时发送自己的引用, self.act 实现自身的再次调用 case "start" => a ! ("hello",self);self.act(); case msg:String => println(msg); } } b ! "start"; } } object U { def main(args:Array[String]):Unit = { // 隐式类型转换 自动将 String 转换为一个包含了你想的给String新加了一个方法的匿名类 implicit def arrayOpt(a: String) = new { def -> (b:String) = (a,b); } // 这里如果将左括号写到下一行 scala 会理解为声明了一个空数组,然后又声明了一个元祖 val z = Array( "name"->"wengmj", "age"->"33" ); for(xx <- z) println(xx); } } object T { def sum(x:List[Int]):Int= x match { case List()=>0; case a::b =>a+sum(b); } //这里可以写成 x => x match 或_ match 或完全省略,但是直接写 x match 是错误的 // 变量直接声明称 函数类型 类型为:x => y 的定义方法 如果又用到了 case 语法,case 前的 变量可以理解为参数声明 val s:List[Int]=>Int = { case List()=>0; case a::b =>a+sum(b); } val t=(x:List[Int])=>x match { case List()=>0; case a::b =>a+sum(b); } def main(args:Array[String]):Unit = { // _@_* 匹配数组的多个元素 val Array(a,_,b,_@_*) = Array(1,2,8,4,5); println(b); println(s(List(1,2,3))); } } object Q { def expr(x:Any) = x match { case 5 => "ok"; case true => "truth"; case s : String => "string"; case _ => "other"; } val exp:Any=>String = { case 5 => "ok"; case true => "truth"; case s : String => "string"; case _ => "other"; } def main(args:Array[String]):Unit = { println(expr(4)); } } object N { def main(args:Array[String]):Unit = { //这个地方是个模式匹配 val State(res) = State("abcdefg") >> (_ * 3) >> (_ drop 3) println(res); } case class State(var s: String) { type Func = String => String def >> (f: Func) = { s = f(s) this } } } object J { //用折叠操作实现列表的反转 def reverse(x:List[Int]):List[Int] = { val f:(List[Int],Int)=>List[Int] = (x,y)=>y::x; val l = List[Int](); (l/:x)(f); } def main(args:Array[String]):Unit = { val x = List(1,2,3,4,5,6,7,8,9); print(reverse(x)); } } //插入排序 object I { val sum:Int=>Int = { case 0 => 0; case x => x+sum(x-1); } val isort:List[Int]=>List[Int] = { case Nil => Nil; case x::xs1 => insert(x,isort(xs1)); } val insert:(Int,List[Int])=>List[Int] = //这里省略 xx match 的意思是整个输入参数的match { case (x,Nil) => List(x); case (x,y::ys) => if(x<=y) x::y::ys; else y::insert(x,ys); } def main(args:Array[String]):Unit = { val x = isort(List(1,4,6,2,3,7,9,5,8)); print(x.mkString(",")); } } object H { def main(args:Array[String]):Unit = { //简明易懂,柯里化函数定义最好用 def x()() 方法定义 def loop1(r: Range)(o: Int=> Unit) {r.foreach(o);} //不容易理解 val loop2 = (r:Range) => (o:Int=>Unit) => r.foreach(o); } } case class BinOp(x:Double,op:String,y:Double); object G { def eval(exp:BinOp):Double = exp match { case BinOp(x,"+",y) => x+y; case BinOp(x,"-",y) => x-y; case BinOp(x,"*",y) => x*y; case BinOp(x,"/",y) => x/y; } def main(args:Array[String]):Unit = { print(eval(BinOp(3,"/",5))); } }