//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);
    }
}
 

  

posted on 2011-06-10 12:17  scala  阅读(593)  评论(0编辑  收藏  举报