//scala 中定义函数的几种方法
def add(x:Int,y:Int):Int =
{
return x+y;//这里的 ruturn 可有可无
}
//这是最标准的效率最高的方法(因为编译后的java代码仍然是一个简单函数)
//但是如果要作为参数传递需要赋值给一个变量 比如 val f = add _; 注意后面必须要哟下划线。
//格式 def 函数名(输入参数和类型列表):返回类型 = {函数定义}
val max = (x:Int,y:Int)=>
{
if(x>y)
x; //这里不能写return
else
y;
}
// 这种定义方式不能实现递归
// val 常量名 = (输入参数和类型列表)=>函数定义
val fact:Int=>Int=x=>
{
if(x==1)
1;
else
x*fact(x-1);
}
//这种定义方式可以实现递归
//val 常量名:(输入参数类型列表)=>返回类型 = (输入参数)=>函数定义
// 这个地方如果没有 lazy 关键字 的话定义常量的同时就会求值,所以里面的递归定义将导致对一个未定义完的变量求值
// 或者将这个变量定义到 main 函数外面 变成一个 object 属性变量,也不会立即求值,再或者将 val 变成 def 定义也不会立即求值
//将匿名函数当做参数传递
def exeFun(f:()=>Unit):Unit=
{
println("before execute fun");
p();
println("after execute fun");
}
//调用
p(()=>println("hello"));
object AA
{
def exeFun(p:(Int,Int)=>Int,x:Int,y:Int):Int=
{
printf("before execute %s\r\n",p);//怎么获取一个函数的名称?
val r = p(x,y);
return r;
}
def main(args:Array[String]):Unit =
{
//这里 先定义一个函数 val p:(Int,Int)=>Int=(x,y)=>{if(x>y) x else y} 然后将变量传入 exeFun(p,3,4);
//或者用匿名函数 写成 exeFun((Int,Int)=>Int=(x,y)=>{if(x>y) x else y},3,4); 是不对的
//exeFun 已经定义了第一个函数的输入输出类型,所以这里直接写参数和用参数就可以了,递归函数不行,因为匿名函数无法递归,递归的时候还不知道引用名
val r = exeFun((x,y)=>{if(x>y) x else y},3,4);
println(r);
}
}
//再搞个复杂点的
object A
{
def main(args:Array[String]):Unit =
{
val printExeFunResult:(Int=>Int,Int)=>Unit = (p,x)=>{print(p(x));}
printExeFunResult(x=>{if(x>0) 1 else 0},8);
}
}
object A
{
def main(args:Array[String]):Unit =
{
lazy val fact_helper:(Int,Int)=>Int = (_:Int,_:Int) match
{
case (1,n)=>n;
case (n,m)=>fact_helper(n-1,n*m);
}
val fact = fact_helper(_:Int,1);
print(fact(10));
}
}
object B
{
def main(args:Array[String]):Unit =
{
val t = new Time();
t.hour = 12;
//注意:定义的时候是成不带括号的方法时(相当于只读属性)就不能带括号调用 但是定义时定义成带空参数括号的方法时调用可带括号也可不带
print(t.hour);
}
}
class Time
{
private [this] var h = 12;
def hour: Int = h;
//本来好看的定义方法是 def hour=(x:Int) 但是 hour= 在 scala 中已经有别的含义了 所以scala 中定义可写属性只能加个下划线了,难看啊
def hour_=(x:Int) {this.h = x;}
}
object A
{
def main(args:Array[String]):Unit =
{
val l = List("cool","tools","rule");
val thrill = "will"::"fill"::"until"::Nil;
val abcd = List("a","b"):::List("c","d");
//println(thrill(2));//返回 thrill的第二个元素 即 until
//println(thrill.count(_.length==4)); //返回 thril 中长度为4的元素数 2
thrill.drop(2); //返回去掉了前两个元素的列表,注意:原列表 thrill 没变
thrill.dropRight(2); //返回去掉了后两个元素的新列表
//print(thrill.exists(_=="until")); //列表中是否存在 until 元素
thrill.filter(_.length==4); //返回长度为4的元素组成的新列表
thrill.forall(_.endsWith("l")); //返回 thrill 中所有的元素是否都是以 l 结尾
//thrill.foreach(s=>print(s));//打印列表 thrill 中的所有元素 还可以 thrill.foreach(print(_)); thrill.foreach(print);
print(thrill.head);//返回第一个元素
thrill.init; //返回最后一个元素外的其他元素,类似的属性还有 isEmpty last length,tail
thrill.map(_+"y");
thrill.mkString(",");
thrill.remove(_.length==4);
thrill.reverse; // reverse 被声明成一个不带括号的方法就有点别扭了,因为它明显不是一个只读属性
thrill.sort((s,t)=>s.charAt(0).toLowerCase<t.charAt(0).toLowerCase);
}
}