first Codec

**public class Friend {public static void main(String[] args){System.out.println("BigData加QQ群:947967114");}
}**

1、隐式转换
通常在处理两个开发时完全不知道对方才能在的软件或类型库时非常有用,他们各自都有自己的方式描述某个概念,而这个概念本质上是描述同一件事。隐式转换可以减少一个类型显示转换成另一个类型的需要。
2、隐式转换规则
隐式定义指可以允许编译器插入程序解决类型错误的定义。比如如果a+b是不能编译,那么编译器会把它改成convert(a)+b的形式,其中convert就是某种转换。如果经过convert修复能够支持+这个动作,就说这个程序是可以修复的。
标记规则:只有标记为implicit定义才可用。,关键字implicit用来标记哪些声明可以被编译器用作隐式定义。可以用implicit来标记任何变量、函数或对象定义。下面有一个隐式函数定义:
implicit def intToString(x:Int):String=x.toString
scala指挥考虑那些在作用域内的隐式转换。所以必须把隐式转换定义引入到当前作用域才可用。

我们把隐式转换说的简单一点,每当编译器看到A类型而它需要的是B类型,编译器就会查找一个能把A转换到B的隐式转换。
例如双精度浮点型不能被用作整数。因为会丢失精度。
scala> val ini:Int=3.14
:15: error: type mismatch;
found : Double(3.14)
required: Int
val ini:Int=3.14
^
如果想让他通过,我们可以写一个隐式转换。
scala> implicit def doubleToInt(a:Double):Int=a.toInt
warning: there was one feature warning; re-run with -feature for details
doubleToInt: (a: Double)Int
这个转换已经成功但是编译器告诉我们一个警告。首先应用隐式转换
scala> val i:Int=3.14
i: Int = 3
现在我们的编译能够正常通过。编译器查找到一个double类型,也就是3.14.但是这里需要的是一个Int,这是一个类型的错误,但是编译器在放弃之前会查找一个从Double到Int的隐式转换。他找到了我们定义的doubleToInt。进行了类型转换,编程了Int也就是3。
那么val i:Int=3.14被编程了val i:Int=doubleToInt(3.14)
这里我们并没有要求进行这样的转换。而是通过把doubleToInt作为标记符纳入到作用域,将他标记为可用的隐式转换。这样编译器就会在需要Double转换成Int时自动使用。
这里我们应该注意到以上的那个警告,警告是在提醒我们应用这个隐式转换会有风险,这里的风险就是精度丢失的问题。Double类型转换成Int会丢失数据的精度。这在程序编写中是不允许的。如果是Int向Double类型转换则是更讲的通。scala就是这么应用的。scala程序引入的对象都定义了那些从小的数值类型向更大的数值类型的隐式转换。例如scala的Predef有如下的转换的定:
implicit def Byte2byte(x: java.lang.Byte): Byte = x.byteValue
implicit def Short2short(x: java.lang.Short): Short= x.shortValue
implicit def Character2char(x: java.lang.Character): Char= x.charValue
implicit def Integer2int(x: java.lang.Integer): Int= x.intValue
implicit def Long2long(x: java.lang.Long): Long= x.longValue
implicit def Float2float(x: java.lang.Float): Float= x.floatValue
implicit def Double2double(x: java.lang.Double): Double= x.doubleValue
implicit def Boolean2boolean(x:java.lang.Boolean):Boolean = x.booleanValue
这些是java的相应类型向scala类型的隐式转换。
还有
implicit def int2double(x:Int):Double=x.toDouble
这样Int类型向double类型的转换,如果我们使用了如下定义:
scala> val i=3
i: Int = 3
我们会看到默认类型是Int,同样我们定义双精度类型最开始的类型依然是Int,这时编译器遇到了错误,编译器就会去查找有没有Int向Double的转换,在scala内找到了相应的转换所以,跳转到了Double类型
scala> val i=3.14
i: Double = 3.14

隐式转换还可以隐式的调用转换后类的方法,例如我们以前的Rational
class Rational(n:Int,d:Int){
require(d!=0)
val numer:Int=n
val demon:Int=d
override def toString=numer+"/"+demon
def +(that:Rational):Rational={
new Rational(
numerthat.demon+that.numerdemon,
demon*that.demon
)
}
}
我们应用的时候
scala> val oneHalf=new Rational(1,2)
oneHalf: Rational = 1/2

scala> val oneHalf1=new Rational(1,2)
oneHalf1: Rational = 1/2
scala> oneHalf + oneHalf1
res113: Rational = 4/4
结果是正确的,但是当我们直接用数字去加一个Rational的时候就有问题了。
scala> 1+ oneHaflf
:18: error: not found: value oneHaflf
1+ oneHaflf
这个问题是因为编译器会检查 1+ oneHaflf,1是Int类型,虽然里面有众多的+的方法,但是没有一个是接收Rational参数的,所以报了类型错误。
这里我们只要做一个隐式转换即可,只要把Int类型转换到Rational类型即可。
scala> implicit def intToRational(x:Int)=new Rational(x,1)
warning: there was one feature warning; re-run with -feature for details
intToRational: (x: Int)Rational
我们再次使用刚刚的运算,就可以得到正确的结果
scala> 1+oneHalf
res115: Rational = 3/2

隐式类:隐式类是以implicit打头的类,对于这样的类编译器会自动生成一个从类的构造方法参数到类的本身的隐式转换。例如:
定义一个类
scala> case class Rectangl(width:Int,height:Int)
defined class Rectangl

scala> implicit class RectangleMake(width:Int){
| def make(height:Int)=Rectangl(width,height)}
defined class RectangleMake

scala> 3 make 4
res116: Rectangl = Rectangl(3,4)
工作过程:因为3并没有make的方法,编译器会查找隐式转换的可能,他将找到RectangleMake的转换类,而RectangleMake确实有一个名为make的方法,编译器就会调用这个方法。
来看两个示例程序:
隐式转换:
class SpPerson(val name:String)
class Student(val name:String)
class Older(val name:String)
class Teacher(val name:String)

object Implaction{
implicit def spPerson(obj:Object):SpPerson={//传Object-任何 类型
if(obj.getClassclassOf[Student]){
//通过object获取类名,是否等于Student
val stu=obj.asInstanceOf[Student]
//实例化Student
new SpPerson(stu.name)
//返回SpPerson类
}
else if(obj.getClassclassOf[Older]){
val older=obj.asInstanceOf[Older]
new SpPerson(older.name)
}else{
Nil
}
}
var ticket=0
def buySpPerson(person:SpPerson)={
ticket=ticket+1
“T-”+ticket
}
}
object test{
import Implaction._
def main(args: Array[String]) = {
val stu1=new Student(“gong”)
println(buySpPerson(stu1))
// 发现Student,但是要求是SpPerson,返回查找看是否有隐式转换
val older=new Older(“oldgongbaoying”)
println(buySpPerson(older))
val teacher=new Teacher(“ss”)
println(buySpPerson(teacher))
//因为Teacher没有隐式转换,返回的是Nil所以会卡住不动了。
}
}
运行结果:
T-1
T-2
程序解析,首先定义了四个类SpPerson表示特殊人群,特殊人群是可以购买车站的半价票,还有Student、Older、Teacher三个类,我们假定Student和Older是特殊人群,而Teacher不是,那么我们要做的就是当遇到Student和Older是就能自动调用SpPerson购买半票的行为,而Teacher或者其他的类型则不能。
接下来定义一个Implaction单例对象,然后定义了一个隐式转换的方法,这个方法的参数是obj:Object,因为我们要传不同的类型进来检查,所有就使用了所有类的超类。然后进行检查if(obj.getClass==classOf[Student]),如果是Student类,那么就先实例化Student类,然后把实例化后的类的参数传递给SpPerson作为实例化的参数。从而实现转化。同理older也是一样的检查。注意最后是一个else,里面给了Nil,因为我们的spPerson方法返回的是SpPerson,不加else就会产生类型不匹配的问题,我们通过所有类型的子类型作为返回值是最好的选择,所以else内是Nil。

通过本例子,能够自己写隐式转换,
超人变身:
class Man(val name:String)
class SuperMan(val name:String) {
def emltiaser = println(“emit a pingpang ball!”)
}
object Implaction02{
implicit def manToSuperMan(man:Man):SuperMan=
new SuperMan(man.name)
def main(args: Array[String]): Unit = {
val dijia=new Man(“dijia”)
dijia.emltiaser
}
}
这是一个男人变超人的例子,这个例子和上一个不同,首先定义了两个类型Man和SuperMan,里面都有一个参数,然后定义了一个单例对象Implaction02,单例对象里做了一个隐式转换manToSuperMan,这里方法给的参数是Man类型,返回类型是SuperMan,返回的方式是直接实例化new SuperMan(man.name)。
在主方法内定义了一个Man实例,让这个实例直接调用SuperMan的方法,如果成功就代表能够进行转化。

隐式参数:
编译器有时会将Call(a)转化为Call(a)(b)或者new Sume(a)转化为new Sume(a)(b)。隐式参数提供的是真个最后一组柯里化的参数列表,不仅仅是一个函数调用。一个简单的例子
class PreferredP(val preferenrence:String)
def greet(name:String)(implicit promt:PreferredP)={
println(“Welcome “+name +”.System is PreferredP”)
println("I’m "+promt)
}

调用,给两个参数,第二个参数是PreferredP,实现了参数的自动调用。
scala> greet(“scala”)(pre)
Welcome scala.System is PreferredP
I’m test

我们再定义一个隐式转化,并且放在一个单例对象中
scala> object JoesPrefs{
implicit val prompt=new PreferredP(“Scala”)
}
defined object JoesPrefs

scala> greet(“joe”)
:25: error: could not find implicit value for parameter promt: Prefe
dP
greet(“joe”)
会发生错误,告诉我们参数给个数不对,我们要调用就要把隐式转换引入到作用域内。
scala> import JoesPrefs._
import JoesPrefs._

scala> greet(“joe”)
Welcome joe.System is PreferredP
I’m Scala
能够正常调用。

以上过程我们再次进行系统的梳理,梳理后再次加入几个小功能,梳理后的程序如下。
class PreferredPrompt(val pro:String)
class PreferredDrink(val prod:String)
object Greeter{
def greet(name:String)(implicit prompt:PreferredPrompt,
drink:PreferredDrink)={
println(“Welcome “+name+“The book is ready”)
println(“while you read”)
println(“why are like”+drink.prod+”?”)
println(prompt.pro)
}
}
object JoesPrefs{
implicit val prompt=new PreferredPrompt(“Yes master”)
implicit val drink=new PreferredDrink(“tea”)
}
我们定义了两个类PreferredPrompt和PreferredDrink,定义了单例对象Greeter,里面有一个隐式转换greet后面的一个隐式参数,是由两个类型组成的,在方法体内调参数的两个属性。此时我们虽然实现了隐式转化,但是greet的第二个参数必须给两个参数才能运行。我们现在想实现只给一个参数就能运行greet。这个方式是通过第二个单例对象JoesPrefs实现。这里面添加了两个隐式参数,分别对应了greet的prompt和drink,当遇到这两个参数类型时,就会调用隐式的类型转换。
同样直接调用一个参数的就会出现问题:
scala> Greeter.greet(“scala”)
:31: error: could not find implicit value for parameter prompt: Pref
edPrompt
Greeter.greet(“scala”)
我们需要把隐式参数转换引入到当前的作用域内:
scala> import JoesPrefs._
import JoesPrefs._
再次调用产生如下结果:
scala> Greeter.greet(“scala”)
Welcome scalaThe book is ready
while you read
why are liketea?
Yes master

大数据Saprk----Spark基础-scala的隐式转换相关推荐

  1. Scalaz(1)- 基础篇:隐式转换解析策略-Implicit resolution

    在正式进入scalaz讨论前我们需要理顺一些基础的scalaz结构组成概念和技巧.scalaz是由即兴多态(ad-hoc polymorphism)类型(typeclass)组成.scalaz typ ...

  2. 深入理解Scala的隐式转换系统

    原文链接:http://www.cnblogs.com/MOBIN/p/5351900.html ---------------------------------------------- 摘要: ...

  3. 深入理解Scala的隐式转换

    摘要: 通过隐式转换,程序员可以在编写Scala程序时故意漏掉一些信息,让编译器去尝试在编译期间自动推导出这些信息来,这种特性可以极大的减少代码量,忽略那些冗长,过于细节的代码. 使用方式: 1.将方 ...

  4. scala之隐式转换

    目录 0.隐式转换定义 1.函数隐式转换 2.使用隐式转换加强现有类型 3.隐式转换函数的作用域与导入 4.隐式参数 5.隐式转换的发生时机 0.隐式转换定义 实现方式:隐式转换函数接收的参数类型定义 ...

  5. Scala的隐式转换详解

    隐式转换是在Scala编译器进行类型匹配时,如果找不到合适的类型,那么隐式转换会让编译器在作用范围内自动推导出来合适的类型. 1.隐式值与隐式参数 隐式值是指在定义参数时前面加上implicit.隐式 ...

  6. Scala自动隐式转换

    底层实现:Scala编译器自动调用了transform方法将5.0转换成Int 在相同作用域内,不能含有多个相同类型的转换规则

  7. 2021年大数据常用语言Scala(三十八):scala高级用法 隐式转换和隐式参数

    目录 隐式转换和隐式参数 隐式转换 自动导入隐式转换方法 隐式转换的时机 隐式参数 隐式转换和隐式参数 隐式转换和隐式参数是scala非常有特色的功能,也是Java等其他编程语言没有的功能.我们可以很 ...

  8. Spark记录-Scala程序例子(函数/List/match/option/泛型/隐式转换)

    object func {def main(args:Array[String]):Unit={//函数赋值给变量时, 必须在函数后面加上空格和下划线.def sayHello(name: Strin ...

  9. scala当中的文件操作、网络请求和隐式转换

    scala当中的文件操作.网络请求和隐式转换 文件操作和网络请求 读取文件当中每一行的数据 读取词法单元和数字 读取网络资源.文件写入.控制台操作 读取网络资源 文件写入操作 控制台交互操作 scal ...

最新文章

  1. 小学六年级下册计算机计划,小学六年级科学下册教学计划(通用5篇)
  2. 【SpringMVC】SpringMVC基础-SpringMVC项目快速搭建、日志框架为logback
  3. 深度学习与模式识别之项目整理
  4. 清华大学梁宸计算机系,2015年广东高考高等学校自主招生录取考生名单公示(2)...
  5. MVP群聊某美国公司的应聘试题(压死九个还是一个)
  6. autoresetevent java_[原创]AutoResetEvent, ManualResetEvent的Java模拟
  7. LeetCode 537. 复数乘法
  8. mysql从服务器配置_mysql主从服务器配置基础教程
  9. 机器人码垛手持式编程_FANUC机器人码垛编程讲解
  10. 编程道场_编码道场教给我有关敏捷的知识
  11. 面试必问:如何实现Redis分布式锁
  12. 字节跳动的首款获批游戏曝光 原来是这个
  13. php定义一个学生类_3分钟短文 | PHP获取函数参数名,和类定义的常量,都要反射...
  14. python debug console_pycharm Python Console调试 django 调试
  15. 1. 物理内存初始化-linux4.0
  16. 刷题集--贪吃的九头龙
  17. iOS-xcode模拟器录屏
  18. 2019下半年第一个流行词---宏颜获水
  19. aspen压缩因子_Aspen物性参数中英文对照
  20. 初识Git与GitHub和使用案例

热门文章

  1. 移动端APP测试总结--转
  2. Java基础之网络编程
  3. 产品周报第27期|会员新增拉黑用户权益;CSDN APP V5.1.0版本发布……
  4. 手势识别整体设计流程方案
  5. mysql查询练习tblstudent_通过Navicat进行MySQL的基础查询练习
  6. Windows10家庭版转为专业版
  7. 论文浅尝 | 基于注意力图卷积神经网络的依存驱动关系抽取
  8. switch函数不加break的效果
  9. Easy_RL 01:强化学习基础
  10. 【车牌识别】RGB颜色模型车牌识别【含GUI Matlab源码 888期】