DT大数据梦工厂- 第5讲 隐式转换和并发编程

来源:互联网 发布:淘宝信用值达到多少 编辑:程序博客网 时间:2024/05/17 09:17
********** 
隐式转换
********** 
1.隐式参数函数
>class Person(val name:String)
>class Engineer(val name:String,val salary:Double)
>new Person("Spark").code//调用Person的code方法出错,无此方法
>class Engineer(val name:String,val salary:Double){
    def code=println("Coding...")
}
>def toCode(p:Person){
    p.code//报错,Person为code方法
}
>implicit def Person2Enginner(p:Person):Engineer={
new Engineer(p.name,1000)
}//定义隐式转换函数
//再写toCode方法
>def toCode(p:Person){
p.code//此时不会报错
}
>toCode(new Person("Scala"))
//自动使用隐式转换函数,在找code方法时,无此方法,将Person对象隐式转换成Engineer对象,
然后就可以调用code方法。此过程是在运行时调用的,自动的进行。
import scala.io.Source
import java.io.File
class RicherFile(val file:File){
   def read = Source.fromFile(file.getPath()).mkString
}
 
class File_Implicits( path: String) extends File(path)
object File_Implicits{
    implicit def file2RicherFile(file:File)= new RicherFile(file) //File -> RicherFile
}

object Implicits_Internals {
    def main(args: Array[String]) {
      val file = new File_Implicits("content.txt")
        println(file.read)
        
    }
}
2.隐式参数
由运行时上下文隐式值注入到你的隐式参数中。
implicit val
implicit var 隐式参数回到隐式参数类型的伴生对象中去找隐式值
>class Level(val level:Int)
>def toWorker(name:String)(implicit l:Level){
    println(name+" : "+l.level)
}
>implicit val lelel=new Level(8)//隐式值
>toWorker("Spark")//上面定义的隐式值在执行过程中系统自动调用
同样也可以传入隐式参数
>toWorker("Spark")(new Level(12))
实例:
object Context_Implicits{
    implicit val default:String = "Flink"
}
 
object Param{
   def print(content:String)(implicit language:String){
      println(language+":"+content)
   }
}
object Implicit_Parameters {

  def main(args: Array[String]) {
    Param.print("Spark")("Scala")
     
    import Context_Implicits._
    Param.print("Hadoop")
  }
}

3.隐式对象
实例:
abstract class Template[T]{
def add(x:T,y:T):T
}
abstract class SubTemplate[T] extends Template[T]{
def unit:T
}
object Implicits_Object{
def main(args:Array[String]){
implicit object StringAdd extends SubTemplate[String]{
def add(x:String,y:String):String=x concat y
def unit:String=""
}
implicit object IntAdd extends SubTemplate[Int]{
def add(x:Int,y:Int):Int=x+y
def unit:Int=0
}
def sum[T](xs:List[T])(implicit m:SubTemplate[T]):T=
if(xs.isEmpty) m.unit
else m.add(xs.head,sum(xs.tail))

println(sum(List(1,2,3,4,5)))
println(sum(List("Spark","Scala","Kafka")))
}
}

4.隐式类

   在四个路径中寻找隐式转换:按优先级查找
a:当前类的伴生对象中找,当前类可能是对象的类或类本身的类
b:所有的隐式转换都放在一个object中,然后import进入
c:在当前作用域中的一些隐式内容中去找
d:用到时写隐式的import导入

import java.io.File
import scala.io.Source
object Context_Helper{
implicit class FileEnhancer(file:File){
def read=Source.fromFile(file.getPath).mkString
}
implicit class Op(x:Int){
def addSAP(second:Int)=x+second
}
}
object Implicits_Class{
def main(args:Array[String]){
import Context_Helper._
println(1.addSAP(2))
println(new File("1.txt").read)
}
}

调用1.addSAP(2):

1没有addSAP方法;向RichInt中去找addSAP方法,没有该方法(系统提供的隐式转换中寻找);
再上下文中寻找,寻找到import导入,将FileEnhancer和Op传入,其中Op的参数是整数,
1为整数,同时Op中有addSAP方法,直接调用addSAP方法。

(隐式类构造时,与类名无关,而与类的签名有关,即(x:Int)有关,编译器自动调用)

********** 
并发编程
********** 

消息通信,缓存机制使用,高效利用CPU,硬件资源

Spark中使用actor做并发编程,Actor去掉了全局共享变量,
每个actor中有自己的私有的变量和方法,actor间可进行发消息进行通信

Akka中也用了Acto。

1.创建一个Actor:
>import scala.actor.Actor
>class HiActor extends Actor{
    def act(){//类似于java的Thread的run
        while(true){//死循环接收消息
            receive{
                case name:String => println("Hi: "+name)
            }
        }
    }
}
>val actor =new HiActor
>actor.start()//启动
>actor!"Spark"//!用于发送消息

2.样例类case class 收发消息

>case class Basic(name :String,age:Int)
>case class Worker(name:String,age:Int,salary:Double)
>class BasicActor extends Actor{
    def act(){
        while(true){
            receive{
                case Basic(name,age) => println(name+" : "+age)
                case Worker(name,age,salary) => println(name+" : "+age+" : "+salary)
            }
        }
    }
}
>val basic=new BasicActor
>basic.start()
>b!Basic("Scala",13)
>b!Worker("Spark",7,15.0)

3.Actor之间发送消息

一个Actor发消息,另一个Actor接收该消息,Spark中类似的有 Master与Worker之间
(3)同步(默认情况下,!发送的消息是异步的)

1.!?:必须等到接收方接收到发送方返回的消息,才结束

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

2.!!:获取异步消息处理之后的消息
>val future =a!!M //存放接收方处理接收到的消息之后返回给发送方的消息
>val result=future//从future中获得异步发送的消息


王老师的名片信息
王家林  中国Spark第一人
DT大数据梦工厂
新浪微博: http://weibo.com.ilovepains/
微信公共号:DT_Spark
博客:http://bolg.sina.com.cn/ilovepains
手机:18610086859
qq:1740415547
邮箱:18610086859@vip.126.com

0 0
原创粉丝点击