目录
隐式转换和隐式参数
隐式转换和隐式参数是scala非常有特色的功能,也是Java等其他编程语言没有的功能。我们可以很方便地利用隐式转换来丰富现有类的功能。
隐式转换
来看一个案例,
-
object SuperIntDemo {
-
def main(args:
Array[
String]):
Unit = {
-
val a:
Int =
1
-
// 使用中缀调用to方法
-
println(a to
10)
-
}
-
}
通过查看Int的源代码,你会惊奇地发现,Int类型根本没有to方法。这难道是让人怀疑人生的大bug吗?
——这其实就是隐式转换的强(gui)大(yi)之处。它在背后偷偷摸摸地帮我们了某种类型转换。
所谓隐式转换,是指以implicit关键字声明的带有单个参数的方法。它是自动被调用的,自动将某种类型转换为另外一种类型。
隐式转换的使用步骤:
在object中定义隐式转换方法(使用implicit)
在需要用到隐式转换的地方,引入隐式转换(使用import)
自动调用隐式转化后的方法
示例:使用隐式转换,让File具备有reada
-
class RichFile(val f:File) {
-
// 将文件中内容读取成字符串
-
def read() =
Source.fromFile(f).mkString
-
}
-
-
object MyPredef {
-
// 定义隐式转换方法
-
implicit
def file2RichFile(f:
File) =
new
RichFile(f)
-
}
-
-
object ImplicitConvertDemo {
-
-
def main(args:
Array[
String]):
Unit = {
-
val f =
new
File(
"./data/textfiles/1.txt")
-
-
// 导入隐式准换
-
import
MyPredef.file2RichFile
-
// 调用的其实是RichFile的read方法
-
println(f.read())
-
}
-
}
-
自动导入隐式转换方法
前面,我们手动使用了import来导入隐式转换。是否可以不手动import呢?
在scala中,如果在当前作用域中有隐式转换方法,会自动导入隐式转换。
示例:将隐式转换方法定义在main所在的object中
-
class RichFile(val f:File) {
-
// 将文件中内容读取成字符串
-
def read() =
Source.fromFile(f).mkString
-
}
-
-
object ImplicitConvertDemo {
-
// 定义隐式转换方法
-
implicit
def file2RichFile(f:
File) =
new
RichFile(f)
-
-
def main(args:
Array[
String]):
Unit = {
-
val f =
new
File(
"./data/textfiles/1.txt")
-
-
// 调用的其实是RichFile的read方法
-
println(f.read())
-
}
-
}
隐式转换的时机
什么时候会自动执行隐式转换呢?
当对象调用中不存在的方法时,编译器会自动将对象进行隐式转换
当方法中的参数类型与目标类型不一致时
示例:
-
object ImplicitConvertDemo {
-
// 定义隐式转换方法
-
implicit
def file2RichFile(f:
File) =
new
RichFile(f)
-
-
def main(args:
Array[
String]):
Unit = {
-
val f =
new
File(
"./data/textfiles/1.txt")
-
-
// test1接收的参数类型为Rich,此时也自动进行了隐式转换
-
test1(f)
-
}
-
-
def test1(r:
RichFile) = println(r.read())
-
}
隐式参数
函数或方法可以带有一个标记为implicit的参数列表。这种情况,编译器会查找缺省值,提供给该方法。
定义隐式参数:
在方法后面添加一个参数列表,参数使用implicit修饰
在object中定义implicit修饰的隐式值
调用方法,可以不传入implicit修饰的参数列表,编译器会自动查找缺省值
示例:
-
// 定义一个分隔符类
-
case
class Delimiters(left:String, right:String)
-
-
object MyPredef1 {
-
implicit
val quoteDelimiters =
Delimiters(
"<<<",
">>>")
-
}
-
-
object ImplicitParamDemo {
-
-
// 使用分隔符将想要引用的字符串括起来
-
def quote(what:
String)(
implicit delims:
Delimiters) = delims.left + what + delims.right
-
-
def main(args:
Array[
String]):
Unit = {
-
println(quote(
"hello, world")(
Delimiters(
"<<",
">>")))
-
-
// 手动导入
-
import
MyPredef1._
-
println(quote(
"hello, world"))
-
}
-
}
和隐式转换一样,可以使用import手动导入隐式参数
如果在当前作用域定义了隐式值,会自动进行导入
转载:https://blog.csdn.net/xiaoweite1/article/details/116810840