大数据之scala(四) --- 模式匹配,变量声明模式,样例类,偏函数,泛型,型变,逆变,隐式转换,隐式参数

一、模式匹配:当满足case条件,就终止
----------------------------------------------------------
    1.更好的switch
        var x = '9';
        x match{
            case '+' => println(" +++ ")
            case '-' => println(" --- ")
            case _ if Character.isDigit(x) => print("is number!");  //带守护条件
            case _   => println(" *** ")                            //相当于 case 中的default
        }

    2.匹配类型
        val x:Any = '1';            //Any所有类型的超类
        x match{
            case a:String => println("is String")
            case b:Int => println("is Int")
            case _ => println("****")
        }

    3.匹配数组
        val arr = Array(0,2)
        arr match {
            case Array(0,1) => println("是数组0,1")            //匹配数组是否是Array(0,1)
            case Array(x,y) => println("是两个元素的数组")      //匹配数组是否只有2个元素
            case Array(0,_*) => println("是以0开始的数组")      //匹配数组是否以0为第一个元素
            case _ => println("***")                           //default
        }


二、变量声明模式
--------------------------------------------
    val x = 100 ;        //
    val t = (1,2,3,4) ;       //元组
    t _1                    //访问元组的第1个元素
    t._1                    //访问元组的第1个元素
    val (a,b,c, d) = t       //解析元组中组员.将元组中的前三个元素赋值给 a,b,c,d


三、样例类 :主要用于模式匹配
-----------------------------------------------
    1.主要用于模式匹配.内置了apply和unapply方法,实现了串行化等接口。创建对象时不需要使用new.
        abstract class Dog{}
        case class Jing8(name:String) extends Dog{}
        case class Shapi(age:Int) extends Dog{}

        //新建对象不需要new,直接应用apply方法
        scala> val d = Jing8("tom")
        d: Jing8 = Jing8(tom)

        //模式匹配
        val d:Dog = new Jing8("tom");
        d match{
            case Jing8(name) => print("是Jing8 : " + name);
            case Shapi(age) => print("是Shapi : " + age);
            case _ => print("aishiuihsui");
        }

    2.密封样例类
        子类和父类必须定义在同一文件中。父类用sealed声明
        sealed abstract class Dog{}
        case class Jing8(name:String) extends Dog{}
        case class Shapi(age:Int) extends Dog{}

四、偏函数
------------------------------------------------
    val f:PartialFunction[Char,Int] = {
        case '+' => 1 ;
        case '-' => -1
        case _ => 0
    }

    scala> f('+')
    res214: Int = 1

    scala> f('-')
    res215: Int = -1

    scala> f('*')
    res216: Int = 0


五、泛型
----------------------------------------------------
    1.泛型类
        //定义一个带有两个类型参数T和S的类。
        class Pair[T,S] (val first:T , val second :S ){    ...    }
        val p = new Pair(42,"String");              // T :Int S :String
        val p = new Pair[Any,Any](42,"String");      // T :Int S :String

    2.泛型函数
        def getMiddle[T] (a:Array[T]) = {
            a(a.length / 2);
        }

        scala> getMiddle(Array(1,2,3,4))
        res218: Int = 3

    3.泛型的界
        a.变量类型的限定
            //要求2个参数的类型相同
            class Pair[T](val first:T , val second :T )

        b. <: 上界:要求泛型T必须是指定的类型的子类
            //泛型T必须是Dog的子类
            def run[T <: Dog](d:T) = println("hello")

        b. >: 下界:要求泛型T必须是指定的类型的超类
            //泛型T必须是Dog的超类
            def run[T >: Dog](d:T) = println("hello")

        c. <% : 要求泛型T必须可以隐式转换成指定类型


六、型变/逆变
------------------------------------------------------
    1.型变[+T]
        class Pair[T] (val first : T, val second : T)
        def makeFriends(p : Pair[Person])       //函数makeFriends的参数p的类型是Pair[Person]
        已知,Student 是 Person的子类,
        但是 makeFriends(new Pair[Person]()) 可以
             makeFriends(new Pair[Student]()) 不可以
        因为虽然Student 是 Person的子类,但是Pair[Person] 和 Pair[Student]没有关系

        如果想Pair[Person] 和 Pair[Student],也具有Student 和 Person一样的关系,就需要声明型变
        class Pair[+T] (val first : T, val second : T)      //+T,表示 pair与T具有相同的继承关系

    2.逆变[-T] -- 型变的反向
        如果,class Pair[-T] (val first : T, val second : T)
        已知,Student 是 Person的子类,
        那么, Pair[Student] 就是 Pair[Person] 的父类


七、隐式转换
----------------------------------------------------------
    1.隐式转换函数
        使用implicit修饰的具有一个参数的函数。把一种类型变换成另外一种类型
            //定义隐式转换函数,当整数和Dog之间可以隐式转换。Dog相当于整数
            //对于int2Dog,是将n:Int的值,赋值给沙皮狗的年龄
            implicit def int2Dog(n:Int) = Shapi(n)
            //run()函数可以传递Dog对象,也可以传递整数
            def run(d:Dog) = print("hello world");
            //调用隐式转换函数。
            scala> run(100) ;
            hello world

    2.在单例对象中定义隐式转换函数
        //定义单例对象
        object DogUtil{
            //定义隐式转换函数
            implicit def str2Dog(s:String) = Jing8(s) ;
        }

        def run3(d:Dog) = println("hello world");

        scala> run3(Jing8("tom"))
        hello world

        //错误是因为,方法是定义在单例类中的,需要先导入才能使用
        scala> run3("tom")
        <console>:17: error: type mismatch;
         found   : String("tom")
         required: Dog
               run3("tom")

        //导入之后就OK了
        scala> import DogUtil._
        import DogUtil._

        scala> run3("tom")
        hello world


八、隐式参数
--------------------------------------------------------------
    1.参数默认值和带名参数
        def decorate(prefix:String = "[[[",c:String,suffix:String="]]]") = ...
        decorate(c= "hello world")

    2.如果有50个函数,都有一个相同的参数,而且这个相同的参数具有相同的值。那么就需要隐式参数了

        //创建隐式变量,dog ==> Jing8("tomas")
        object DogUtil2{
            implicit val dog = Jing8("tomas") ;
        }

        import DogUtil2._
        //创建带有隐式参数的函数
        def run4(implicit dog:Jing8) = println("hello : ") ;

        run4();

























猜你喜欢

转载自blog.csdn.net/xcvbxv01/article/details/83689534