zoukankan      html  css  js  c++  java
  • Scala 高级编程练习

    定义自己的控制结构,使它语言内置的用法一样

    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+

  • 相关阅读:
    安富莱周报摘录
    关于MQTT:
    JavaScript高级用法三之浏览器对象
    编写高性能Web应用程序的10个技巧
    JavaScript高级用法二之内置对象
    JavaScript高级用法一之事件响应与网页交互
    eval、json.parse()的介绍和使用注意点
    史上最详细的JavaScript事件使用指南
    Image Lazy Load:那些延时加载图片的开源插件(jQuery)
    不要去管浏览器兼容
  • 原文地址:https://www.cnblogs.com/scala/p/3632707.html
Copyright © 2011-2022 走看看