一、Scala隐式转换
1. 方法中参数的类型与实际类型不一致,进行隐式转换
2. 调用类中不存在的方法或成员时,会自动将对象进行隐式转换
(一)隐式转换函数
//上下文中定义了隐式转换函数
scala> class Person(val name:String)
defined class Person
scala> class Engineer(val name:String, val salary:Double){
| def code = println("Coding ...")
| }
defined class Engineer
scala> def toCode(p: Person){ Person类中无code方法,报错
| p.code
| }
<console>:9: error: value code is not a member of Person
p.code
scala> new Person("Spark").code //Person类中无code方法,报错
<console>:9: error: value code is not a member of Person
new Person("Spark").code
scala> implicit def person2Engineer(p:Person):Engineer = { //定义隐式转换函数
| new Engineer(p.name, 1000000)
| }
warning: there were 1 feature warning(s); re-run with -feature for details
personToEngineer: (p: Person)Engineer
scala> def toCode(p: Person){ //因为已经定义了隐式转换函数,调用code方法成功
| p.code
| }
toCode: (p: Person)Unit
scala> toCode(new Person("Scala")) //此时new Person实际调用了new Engineer,产生的是Engineer
Coding ...
//隐式转换举例
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)
}
object Implicit_Internals {
def main(args:Array[String]){
val file = new File_Implicits("D:/word.txt")
println(file.read)
}
}
(二)隐式参数
运行时由上下文实际赋值注入的参数,不需要手动赋值。
implicit val
implicit var
在隐式参数类型的伴生对象中找隐式值。
要想隐式参数只为函数中的某一个参数,则必须对函数进行柯里化。若函数未柯里化,即使implicit只出现一次,所有参数也都被声明为了隐式参数。
scala> class Level(val level: Int)
defined class Level
scala> def toWorker(name:String)(implicit l:Level) = println(name + ":" + l.level)
toWorker: (name: String)(implicit l: Level)Unit
scala> implicit val level = new Level(8)
level: Level = Level@4b3c354a
scala> toWorker("Spark")
Spark:8
object Context_Implicits{
implicit val default:String = "HBase"
}
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") //隐式
}
}
//Scala:Spark
//HBase:Hadoop
(三)隐式对象
隐式转换一般写在伴生对象中。
abstract class Template[T]{
def add(x:T, y:T): T
}
abstract class SubTemplate[T] extends Template[T]{
def unit: T
}
object Implicit_Object {
def main(args:Array[String]){
implicit object StringAdd extends SubTemplate[String]{
override def add(x:String, y:String) = x concat y
override def unit:String = ""
}
implicit object IntAdd extends SubTemplate[Int]{
override def add(x:Int, y:Int) = x + y
override 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)) //xs.tail除第一个元素外其他元素组成的集合,递归调用
println(sum(List(1,2,3,4,5)))
println(sum(List("Spark","Scala","Hadoop")))
}
}
//15
//SparkScalaHadoop
(四)隐式类
import scala.io.Source
import java.io.File
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 Implicit_Class extends App {
import Context_Helper._
println(1.addSAP(2)) //直接调用addSAP方法
println(new File("word").read)
}
//3
//scala spark
二、并发编程
并发编程对于高效利用资源很重要。Scala中提供Actor支持并发编程,类似于Java中的Thread,而Thread基于共享全局变量的加锁机制,容易出现死锁。Actor中变量私有,解决了Thread的这一问题。
scala> import scala.actors.Actor
import scala.actors.Actor
scala> class HiActor extends Actor{
| def act(){
| while(true){ //死循环,不断检查接受消息
| receive {
| case name:String => println(name)
| }
| }
| }
| }
defined class HiActor
scala> val actor = new HiActor
actor: HiActor = HiActor@2e5b7fba
scala> actor.start() //启动
res4: scala.actors.Actor = HiActor@2e5b7fba
scala> actor ! "Spark" //发送消息给actor
Spark
scala> case class Basic(name:String, age:Int)
defined class Basic
scala> case class Worker(name:String, age:Int)
defined class Worker
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)
| }
| }
| }
| }
defined class basicActor
scala> val b = new basicActor
b: basicActor = basicActor@5e5ddfbc
scala> b.start
res6: scala.actors.Actor = basicActor@5e5ddfbc
scala> b ! Basic("Scala", 13)
Basic Information:Scala 13
scala> b ! Worker("Spark", 9)
Worker Information:Spark 9