Spark学习笔记5-隐式转换,隐式参数,隐式类

来源:互联网 发布:神马快递单打印软件 编辑:程序博客网 时间:2024/06/07 14:24

1. 隐式转换,隐式参数,隐式类

scala中隐式转换,隐式参数,隐式类用到的标志符是implicit。

1.1隐式转换

scala> class Person(val name: String)defined class Personscala> class Engineer(val name: String, val salary: Double){     | def code = println("Coding ... "+name+" : "+salary)     | }defined class Engineerscala> implicit def person2Engineer(p: Person): Engineer={     | new Engineer(p.name,1000000)     | }warning: there was one feature warning; re-run with -feature for detailsperson2Engineer: (p: Person)Engineerscala> def tocode(p: Person){     | p.code     | }tocode: (p: Person)Unitscala> tocode(new Person("Scala"))Coding ... Scala : 1000000.0

上述程序中运行tocode函数中参数是一个Person类的一个对象p,再里面调用了一个p.code方法。但是从class Person的定义中可以看出,定义里并没有code方法,这个时候编译器就会开始找是否有对应的隐式转换可用,根据参数找到implicit def person2Engineer(p: Person)这个函数,再在里面调用Engineer 类里面的println(“Coding … “+name+” : “+salary)方法。
所以最后打印的结果是:
Coding … Scala : 1000000.0

1.2 隐式参数

注:一般从隐式参数类型的伴生对象中找隐式值。

scala> class Level(val level: Int)defined class Levelscala> def toWorker(name : String)(implicit l : Level) = println(name + " : "+l.level)toWorker: (name: String)(implicit l: Level)Unitscala> implicit val level =new Level(8)level: Level = Level@17c1bcedscala> toWorker("Spark")Spark : 8

隐式参数在意义上于隐式转换类似,只是针对值做下而已。
从上述参数中可以看出toWorker第一个参数是string类型的,是确定的。第二个餐时是implicit描述的 Level类型的,是个隐式参数。所以在运行toWorker(“Spark”)时候,虽然没有第二个参数,但是编译器求寻找隐式参数,结果从implicit val level =new Level(8)中找到l的值为8.所以结果为:
Spark : 8

1.3 隐式类

scala> implicit class Test(x:Int){     | def add(a:Int):Int =a+x     | }defined class Testscala> println("5.add(6)=" + 5.add(6))5.add(6)=11

上例先定义了隐式类implicit class Test,调用的时候用5.add(6),编译时先是找不到5.add方法,再找其隐式类来计算。

上面的例子等同于下面:

scala> println("5.add(6)=" + Test(5).add(6))5.add(6)=11

2. 并发编程

并发编程用acotr,相当于java中的thread。
先要导入scala.actors.Actor

scala> import scala.actors.Actorimport scala.actors.Actor

例子1:直接传入参数

scala> class HiActor extends Actor{     | def act(){     |     while(true){     | receive {     | case name: String => println(name)     | }     | }     | }     | }warning: there was one deprecation warning; re-run with -deprecation for detailsdefined class HiActorscala> val actor = new HiActoractor: HiActor = HiActor@7a138fc5scala> actor.start()res4: scala.actors.Actor = HiActor@7a138fc5scala> actor ! "Spark"Spark

例子中最后的一个程序中的!后面跟的事传入的内容。

例子2:直接传入函数

scala> class basicActor extends Actor{     | def act(){     | while(true){     | receive{     | case Basic(name,age) => println("Basic Information: " + name +" : "+age)     | case Worker(name,age) => println("Worker Information: "+ name +" : "+age)      | }     | }     | }     | }warning: there was one deprecation warning; re-run with -deprecation for detailsdefined class basicActorscala> val b = new basicActorb: basicActor = basicActor@2e5b7fbascala> b.startres6: scala.actors.Actor = basicActor@2e5b7fbascala> b ! Basic("Scala",13)Basic Information: Scala : 13scala> b ! Worker("Spark",7)Worker Information: Spark : 7

上面的两个例子都是异步完成发消息的。
下面介绍下同步发消息,如下:

scala> val result = b !? Worker("Spark",7)Worker Information: Spark : 7

如果要获得异步消息的返回值,这个时候就要2个感叹号了。

scala> val futureb !! Worker("Spark",7)

XianMing

0 0