# Scala入门到精通——第十八节 隐式转换与隐式参数（一）

1. 隐式转换简介
2. 隐式转换函数
3. 隐式转换规则
4. 隐式参数

## 2. 隐式转换函数

scala> val x:Int=3.5
<console>:7: error: type mismatch;
found   : Double(3.5)
required: Int
val x:Int=3.5
^

//定义了一个隐式函数double2Int，将输入的参数
//从Double类型转换到Int类型
scala> implicit def double2Int(x:Double)=x.toInt
warning: there were 1 feature warning(s); re-run with -feature for details
double2Int: (x: Double)Int
//定义完隐式转换后，便可以直接将Double类型赋值给Int类型
scala> val x:Int=3.5
x: Int = 3

package cn.scala.xtwy

import java.io.File
import scala.io.Source
class RichFile(val file:File){
}

object ImplicitFunction extends App{
implicit def double2Int(x:Double)=x.toInt
var x:Int=3.5
//隐式函数将java.io.File隐式转换为RichFile类
implicit def file2RichFile(file:File)=new RichFile(file)
println(f)
}

## 3. 隐式转换规则

implicit def double2Int(x:Double)=x.toInt
var x:Int=3.5

package cn.scala.xtwy
import java.io.File
import scala.io.Source

//在cn.scala.xtwy包中定义了子包implicitConversion
//然后在object ImplicitConversion中定义所有的引式转换方法
package implicitConversion{
object ImplicitConversion{
implicit def double2Int(x:Double)=x.toInt
implicit def file2RichFile(file:File)=new RichFile(file)
}

}

class RichFile(val file:File){
}

object ImplicitFunction extends App{
//在使用时引入所有的隐式方法
import cn.scala.xtwy.implicitConversion.ImplicitConversion._
var x:Int=3.5

println(f)
}

scala> :implicits -v
/* 78 implicit members imported from scala.Predef */
/* 48 inherited from scala.Predef */
implicit def any2ArrowAssoc[A](x: A): ArrowAssoc[A]
implicit def any2Ensuring[A](x: A): Ensuring[A]
implicit def any2stringfmt(x: Any): runtime.StringFormat
implicit def boolean2BooleanConflict(x: Boolean): Object
implicit def byte2ByteConflict(x: Byte): Object
implicit def char2CharacterConflict(x: Char): Object
implicit def double2DoubleConflict(x: Double): Object
implicit def float2FloatConflict(x: Float): Object
implicit def int2IntegerConflict(x: Int): Object
implicit def long2LongConflict(x: Long): Object
implicit def short2ShortConflict(x: Short): Object

//....................


1 当方法中参数的类型与实际类型不一致时，例如

def f(x:Int)=x
//方法中输入的参数类型与实际类型不一致，此时会发生隐式转换
//double类型会转换为Int类型，再进行方法的执行
f(3.14)

2 当调用类中不存在的方法或成员时，会自动将对象进行隐式转换，例如：

package cn.scala.xtwy

import java.io.File
import scala.io.Source
class RichFile(val file:File){
}

object ImplicitFunction extends App{
implicit def double2Int(x:Double)=x.toInt
var x:Int=3.5
//隐式函数将java.io.File隐式转换为RichFile类
implicit def file2RichFile(file:File)=new RichFile(file)
//将File类转换成RichFile
println(f)
}

1 编译器可以不在隐式转换的编译通过，则不进行隐式转换，例如

//这里定义了隐式转换函数
scala> implicit def double2Int(x:Double)=x.toInt
warning: there were 1 feature warning(s); re-run with -feature for details
double2Int: (x: Double)Int

//下面几条语句，不需要自己定义隐式转换编译就可以通过
//因此它不会发生前面定义的隐式转换
scala> 3.0*2
res0: Double = 6.0

scala> 2*3.0
res1: Double = 6.0

scala> 2*3.7
res2: Double = 7.4


2 如果转换存在二义性，则不会发生隐式转换，例如

package implicitConversion{
object ImplicitConversion{
implicit def double2Int(x:Double)=x.toInt
//这里定义了一个隐式转换
implicit def file2RichFile(file:File)=new RichFile(file)
//这里又定义了一个隐式转换，目的与前面那个相同
implicit def file2RichFile2(file:File)=new RichFile(file)
}

}

class RichFile(val file:File){
}

object ImplicitFunction extends App{
import cn.scala.xtwy.implicitConversion.ImplicitConversion._
var x:Int=3.5

//下面这条语句在编译时会出错，提示信息如下：
//type mismatch; found : java.io.File required:
// ?{def read: ?} Note that implicit conversions
//are not applicable because they are ambiguous:
//both method file2RichFile in object
//ImplicitConversion of type (file:
//java.io.File)cn.scala.xtwy.RichFile and method
//file2RichFile2 in object ImplicitConversion of
//type (file: java.io.File)cn.scala.xtwy.RichFile
//are possible conversion functions from java.io.File to ?{def read: ?}
value read is not a member of java.io.File

println(f)
}

3 隐式转换不会嵌套进行，例如

package cn.scala.xtwy
import java.io.File
import scala.io.Source

package implicitConversion{
object ImplicitConversion{
implicit def double2Int(x:Double)=x.toInt
implicit def file2RichFile(file:File)=new RichFile(file)
//implicit def file2RichFile2(file:File)=new RichFile(file)
implicit def richFile2RichFileAnother(file:RichFile)=new RichFileAnother(file)
}

}

class RichFile(val file:File){
}

class RichFileAnother(val file:RichFile){
}

object ImplicitFunction extends App{
import cn.scala.xtwy.implicitConversion.ImplicitConversion._
var x:Int=3.5

//隐式转换不会多次进行，下面的语句会报错
//不能期望会发生File到RichFile，然后RifchFile到
//RichFileAnthoer的转换
println(f)
}

## 4. 隐式参数

package cn.scala.xtwy

class Student(var name:String){
//将Student类的信息格式化打印
def formatStudent(outputFormat:OutputFormat)={
outputFormat.first+" "+this.name+" "+outputFormat.second
}
}

class OutputFormat(var first:String,val second:String)

object ImplicitParameter {
def main(args: Array[String]): Unit = {
val outputFormat=new OutputFormat("<<",">>")
println(new Student("john").formatStudent(outputFormat))
}
}
//执行结果
//<< john >>

package cn.scala.xtwy
class Student(var name:String){
//利用柯里化函数的定义方式，将函数的参数利用
//implicit关键字标识
//这样的话，在使用的时候可以不给出implicit对应的参数
def formatStudent()(implicit outputFormat:OutputFormat)={
outputFormat.first+" "+this.name+" "+outputFormat.second
}
}

class OutputFormat(var first:String,val second:String)

object ImplicitParameter {
def main(args: Array[String]): Unit = {
//程序中定义的变量outputFormat被称隐式值
implicit val outputFormat=new OutputFormat("<<",">>")
//在.formatStudent()方法时，编译器会查找类型
//为OutputFormat的隐式值,本程序中定义的隐式值
//为outputFormat
println(new Student("john").formatStudent())
}
}

|
4月前
|

Scala入门必刷的100道练习题（附答案）
Scala入门必刷的100道练习题（附答案）
536 1
|
4月前
|
Java 大数据 Scala
Scala入门【运算符和流程控制】
Scala入门【运算符和流程控制】
61 0
|
23天前
|

Scala 入门指南：从零开始的大数据开发
Scala 入门指南：从零开始的大数据开发
26 0
|
2月前
|

49 0
|
2月前
|
IDE 大数据 Java
「AIGC」大数据开发语言Scala入门
Scala，融合OOP和FP的多范式语言，在JVM上运行，常用于大数据处理，尤其与Apache Spark配合。要开始学习，安装Scala，选择IDE如IntelliJ。基础包括变量、数据类型、控制结构、函数。Scala支持类、对象、不可变数据结构、模式匹配和强大的并发工具。利用官方文档、教程、社区资源进行学习，并通过实践提升技能。
38 0
|
3月前
|

scala-柯里化、隐式转换、泛型、upperbound、viewbound、contextBound
scala-柯里化、隐式转换、泛型、upperbound、viewbound、contextBound
22 0
|
10月前
|
Scala
173 Scala 隐式转换和隐式参数
173 Scala 隐式转换和隐式参数
28 0
|
4月前
|
SQL 分布式计算 编译器
Scala：高阶函数、隐式转换(四)
Scala：高阶函数、隐式转换(四)
41 0
|
4月前
|
Java Shell API
Scala入门【变量和数据类型】
Scala入门【变量和数据类型】
59 0
|
11月前
|

Scala语言入门：初学者的基础语法指南

62 0