开发者学堂课程【Scala 核心编程-基础:隐式值详解】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/609/detail/9009
隐式值详解
内容介绍
一、基本介绍
二、应用案例
三、课堂测试题
一、基本介绍
隐式值也叫隐式变量,将某个形参变量标记为 implicit,所以编译器会在方法省略隐式参数的情况下去搜索作用域内的隐式值作为缺省参数。scala 中的默认值,默认值只能作用在一个函数的一个形参上,但是隐式值可以作用在多个函数的形参上,它的范围更加广泛。
二、应用案例
implicit val str1: String = "jack"
def hello(implicit name: String): Unit = {隐式参数
println(name + " hello")
hello
//调用.不带()
//[案例演示+反编译]
1、创建 ImplicitValDemo03,选择 object。
package com. atguigu. chapter09
object ImplicitValDemo03
{
Def
main(args: Array[String]): Unit =
{
implicit val str1: String = "jack"
//这个就是隐式值,implicit 修饰 str1变量
//implicit name: String:name 就是隐式参数
def hello(implicit name: String): Unit = {
println(name + " hello")
}
Hello
//
底层 hello
(
‘’
jack
~
‘’
)
}
}
这时 name 会将 jack 自动传进去。
运行结果如下:
Jack hello
2、打开底层实现,ImplicitValDemo03$.class。
package com. atguigu. chapter09;
import scala.Predef.;
public final class Implici tValDemo03$
{
public static final
MODULE$;
Static
{
new () ;
}
pub1ic void main (String[] args)
{
String str1 = "jack~";
hello$1 (str1) ;
采用第一种方式
}
private final void hello$1 (String name )
{
Predef. . MODULE$. println (new StringBuilder () . append (name) .append(" hello") . toString());
}
private ImplicitValDemo03$ ()
{
MODULE$ . this;
}
}
Hello
//
底层hello$1 (str1)
;
三、课堂测试题
1、下面的代码是正确,并解释 scala 底层实现机制,底层的函数名。
object ImplicitVal
{
def main(args: Array[String]): Unit =
{
主函数
implicit val str1: String = "jack"
//隐式值
def hello(implicit name: String): Unit = (
{
//底层生成 hello$1
println(name + " hello")
def hello(): Unit =
{//
生成
hello$
2
println("xxxx")
}
}
hello
/
/
hello$1 (str1)
使用隐式值不要带(),写了会报错,如果明确写(),意图就是调用hello,不传任何参数,语法错误
}
def hello(): Unit = ( /
/
函数名
hello
println("xx")
}
}
2、看下面几个案例,判断是否正确
(1)创建 ImplicitVal02,选择 object。
object ImplicitVal02 {
def main(args: Array[String]): Unit= {
//隐式变量(值)
implicit val name: String = "Scala"
//implicit val name1: String = "World"
//隐式参数
def hello(implicit content: String = "jack"): Unit= {
println("Hello " + content)
} //调用 hello
Hello
}
}
运行会报错,提示模糊不确定,因为编译器只能匹配一个,所以把其中一个注销。
第一题是错误的,编译器会报错,再次证明隐式具有一致性,不能有二义性。
(2)object Scala03 {
def main(args: Array[String]) : Unit = {
//隐式变量(值)
implicit val name : String = "Scala"
//当同时有 implicit 值和默认值,implicit 优先级高
def hello2( implicit content : String = "okook" ) : Unit = {
println("He
ll
o2" + content)
}
//调用 hello
Hello2
}
}
输出什么内容?
implicit 直接在编译器写进去,所以级别要比默认高。
输出 hello2 scala。
(3)object Scala03 {
def main(args: Array[String]) : Unit = {
//隐式变量(值)
//说明
//1.当一个隐式参数匹配不到隐式值,仍然会使用默认值
implicit val name : Int = 10
def hello3( implicit content : String = "
jack
" ) : Unit = {
println("Hello3" + content )
}
//调用 hello
Hello3//
hello
3
jack
}
}
输出什么内容?
输出 hello jack。
虽然标记成隐式参数,但是在没有匹配到隐式值时仍然会去使用默认值,并不会报错。
(4)object Scala03 {
def main(args: Array[String]) : Uni t = {
//隐式变量(值)
implicit val name:Int=10
//当没有隐式值,没有默认值,又没有传值,就会报错。
def hello4( implicit content : String ) : Uni t = {
隐式参数
println(" Hello4" + content )
}
//调用 hello
hello 4
}
输出什么?
会报错。
把默认值去掉,首先找隐式值,会找到是int型,默认值没有给,不传值,所以匹配不到,比如有隐式值,默认值,传值,优先传值,当三者都有,指定优先级最高的,传值,隐式值,默认值,如果都匹配不到,就报错。
目前是又没有传参数,又没有隐式值,又没有默认值,所以一定会报错,会在36行抛出一个错误,执行查看提示36行有错误。
//小结
//1.当在程序中, 同时有隐式值,默认值,传值
//2.编译器的优先级为传值>隐式值>默认值
//3.在隐式值匹配时,不能有二义性
//4.如果三个(隐式值,默认值,传值)一个都没有,就会报错。
隐式值的案例是快速入门的案例。
一个案例说明隐式值,默认值,传值的优先级问题。