定义自己的控制结构,使它语言内置的用法一样
package exp object Main { def enableCustomerIF = false; def main(args: Array[String]): Unit = IF(1 / 0 == 0) // 这里就不用写 IF(()=>3>2)(()=>println("hello"); {//这不是语言内置的IF,大括号可不能省略 List("hello","world") foreach println; } //()=>Boolean 替换成 =>Boolean 就可以实现在不传递参数时省略掉()=>了,为避免歧义要在:与=>之间多留一些空格 def IF(condition: => Boolean)(op: => Unit): Unit = //如果 condition 的类型定义成 Boolean表达式 而不是 =>Boolean的函数的话 禁用 enableCustomerIF 也会报错 if (enableCustomerIF && condition) //condition 是函数调用,因此1/0==0在 enableCustomerIF=false时不会执行 op; //op的定义如果是()=>Unit 执行时就要带括号了 }
定义类的可读\写属性
package exp object Main { def main(args: Array[String]): Unit = { val s = new Stu; s.age = 10; println(s.age); } } class Stu { private var n = ""; private var g = 0; def name = this.n; def name_=(x: String): Unit = this.n = x;//这个定义更标准,生成的代码也很简单 def age = this.g; def age_= = this.g = _: Int;//这个定义看上去很简单,更函数式,但是不好理解生成的代码更复杂 }
模式匹配实现的表达式解析
package exp { object Main { def simplifyTop(ex: Expr): Expr = ex match { case UnOp("-", Var(x)) => Var("-" + x); case UnOp("-", UnOp("-", e)) => simplifyTop(e); case BinOp("+", e, Number(0)) => e; case BinOp("*", e, Number(1)) => e; case BinOp("+", Var(x), Var(y)) => Var(x + y); case BinOp("+", a, b) => BinOp("+", simplifyTop(a), simplifyTop(b)) case _ => ex; } def main(args: Array[String]): Unit = { val x = simplifyTop(BinOp("+", Var("x"), Var("y"))); println(x); } abstract class Expr; case class Var(name: String) extends Expr; case class BinOp(op: String, left: Expr, right: Expr) extends Expr; case class Number(num: Double) extends Expr; case class UnOp(op: String, arg: Expr) extends Expr; } }
foreach 迭代器和 for (p <- x) 循环迭代是不太一样的
object Main { def main(args: Array[String]): Unit = { val x = 1 to 10; var i = 0; x.foreach { // i = i+1; 放在这里只执行一次 , foreach 和 for(p <- x) 迭代器还是不一样的 p =>{ i = i + 1; //放在这里会执行10次 println(p); } } println(i) i = 0; for (p <- x) { i = i + 1; //执行10次 println(p); } println(i); } }
package exp { object Main { def main(args: Array[String]): Unit = { //数组传递给可变参数 :_* def sum(x:Int*)=x.sum; println(sum(Array(1,2,3):_*)) //匹配数组或列表多个元素 _* val Array(a,_,b,_*) = Array(1,2,3,4,5); println(b); val List(c,_,d,_*) = List(1,2,3,4,5,6) println(d); //模式匹配上变量绑定 @ case UnOp("abs",e@UnOp("abs",_)) => e } } }
Option 类型的使用
package exp { object Main { def main(args: Array[String]): Unit = { div(8,1) match{ case None => println("none"); case Some(y) => println(y); } } def div(x:Int,y:Int):Option[Int] = if(y==0) None else Some(x/y) } }
各种格式的函数定义
val foo : Int=>Int = x => x match {
case 0 => 0;
case x => x+1;
}
val foo1 : Int=>Int = _ match {
case 0 => 0;
case x => x+1;
}
val foo2 : Int=>Int ={ //能省略掉match的只有这一种情况,指定函数类型变量,在case中直接用样本定义函数
case 0 => 0;
case x => x+1;
}
val foo3 = (x:Int) => x match {
case 0 => 0;
case x => x+1;
}
def foo4(x:Int):Int = x match {
case 0 => 0;
case x => x+1;
}
def foo5(x:Int):Int = {
x match
{
case 0 => 0;
case x => x+1;
}
}
定义返回函数的函数
def main(args: Array[String]): Unit = { val f = (x:Int) => (y:Int)=>x+y; println(f(3)(2)); val g:Int=>Int=>Int = x=>y=>x+y; println(g(3)(2)); def fxx(x:Int)(y:Int) = x+y; println(fxx(3)(2)); def foo(x:Int) = { val tmp = (y:Int) => x+y; tmp; } println(foo(3)(2)); def foo1(x:Int) = { def tmp(y:Int) = x+y; tmp _; } println(foo1(3)(2)); }
如果函数只有一个变量,并且这个变量在最末尾,则这个变量的下划线也可以省略
def foo(add:Int=>Int):Int= add(2);
println(foo(2+));//p=>2+p 或 2+_ 或 2+