package imp
/*
* 隐式转换函数:把double 转成 int
*/
object imp01 {
implicit def double2int(d:Double):Int = {
println("调用 double2int")
d.toInt
}
def main(args: Array[String]): Unit = {
var i:Int = 1;
val d:Double = i // 把Int --> double 。隐式转换。把精度低的数据转成精度高的数据,这是可以的!!!
i = 1.5 // 把double ---> int 。把高精度的转成低精度的的,错误!!!!
printun(i)
}
}
1. 定义了一个 “隐式转换函数”
implicit def double2int(d:Double):Int 的作用是:自动将Double类型的值转换为Int类型(转换时会调用d.toInt,同时打印 “调用 double2int”)。
2. 演示 “数值类型的隐式转换规则”
val d:Double = i:把Int(低精度)转成Double(高精度),这是Scala 默认支持的隐式转换,所以可以直接赋值。i = 1.5:尝试把Double(高精度)转成Int(低精度),默认不允许直接转换,但因为定义了double2int这个隐式转换函数,Scala 会自动调用它完成转换。
3. 代码的实际执行效果
当运行main方法时:
- 先定义
Int类型的i=1,然后赋值给Double类型的d(自动隐式转换,无报错)。 - 执行
i = 1.5时,Scala 会自动调用double2int(1.5),将1.5转成Int类型的1,同时打印 “调用 double2int”。 - 最后执行
printun(i)(注:代码里这里应该是笔误,正确写法是println(i)),输出转换后的i值(即1)。
/*
隐式函数
1. implicit 修饰。
2. 它会自动被调用。当系统检测到隐式转换失败的时候,去自动调用。
3. 函数的名字不重要,重要的是它的输入参数的类型和返回值类型
它的作用是:偷偷地把一种类型的数据转成另一种类型的数据!
*/
object imp01 {
implicit def double2int(d:Double):Int = {
println("调用 double2int")
d.toInt
}
def main(args: Array[String]): Unit = {
var i:Int = 1;
val d:Double = i // 把int --> double 。隐式转换。把精度低的数据转成精度高的数据,这是可以的!!!
i = 1.2 // 把double ---> int 。把高精度的转成低精度的的,错误!!!!
i = 2.2
i = 3.3
println(i)
}
}
1. 隐式函数的定义
scala
implicit def double2int(d: Double): Int = {
println("调用 double2int")
d.toInt
}
-
implicit是 Scala 中的关键字,用来修饰 “隐式函数”。 -
隐式函数的特点:在类型不匹配的时候,Scala 会自动调用它进行类型转换。
-
这个函数的功能:
- 输入:一个
Double类型的值。 - 输出:将
Double转成Int(直接截断小数部分)。 - 每次调用会打印
"调用 double2int"。
- 输入:一个
-
注意:隐式函数的名字(这里是
double2int)不重要,重要的是参数类型和返回值类型。
2. main 方法逻辑
scala
def main(args: Array[String]): Unit = {
var i: Int = 1;
val d: Double = i // 把 int --> double 。隐式转换。把精度低的数据转成精度高的数据,这是可以的!!!
i = 1.2 // 把 double ---> int 。把高精度的转成低精度的的,错误!!!!
i = 2.2
i = 3.3
println(i)
}
2.1 val d: Double = i
i是Int类型,d是Double类型。- 因为
Int是低精度,Double是高精度,Scala 默认允许这种自动转换(不会丢失信息)。 - 这里没有调用我们自定义的
double2int,而是用了内置的隐式转换。
2.2 i = 1.2 / i = 2.2 / i = 3.3
-
i是Int类型,右边是Double类型。 -
默认情况下,Scala 不允许高精度类型直接赋值给低精度类型,因为可能会丢失信息。
-
但是,因为我们定义了
implicit def double2int,Scala 会自动调用这个函数,把Double转成Int。 -
每次赋值都会:
- 打印
"调用 double2int" - 用
d.toInt截断小数部分。
- 打印
2.3 println(i)
-
最终
i的值是最后一次转换的结果:3.3→3。 -
输出:
plaintext
调用 double2int 调用 double2int 调用 double2int 3
3. 运行结果示例
plaintext
调用 double2int
调用 double2int
调用 double2int
3
4. 总结
- 隐式函数:在类型不匹配时自动调用,用来实现类型转换。
- 隐式函数的参数类型和返回值类型决定了它什么时候被调用。
- 高精度转低精度,默认是禁止的,但可以用隐式函数绕过。
- 隐式转换可以让代码更简洁,但也要小心使用,避免隐藏类型转换逻辑。
package imp
/*
* 隐式参数:如果在写函数的参数的时候,预计某个参数的默认值可能会被修改。可以设置隐式参数。
*
* implicit password:String="123456"
*
*/
object imp02 {
implicit val defaultPassword:String = "88888888"
def reg( name:String)(implicit password:String="123456"):Unit = {
println(s"用户名:${name}, 密码: ${password}")
}
def main(args: Array[String]): Unit = {
reg("小花")
reg("小明")("admin")
}
}
1. 隐式参数的定义
scala
implicit val defaultPassword: String = "88888888"
implicit修饰一个val(常量),表示它是一个隐式值。- 隐式值的作用:当函数参数列表中有
implicit参数,且调用时没有显式传值时,Scala 会在当前作用域中寻找匹配类型的隐式值来自动传入。 - 这里定义了一个
String类型的隐式值defaultPassword,值为"88888888"。
2. 函数定义
scala
def reg(name: String)(implicit password: String = "123456"): Unit = {
println(s"用户名:${name}, 密码: ${password}")
}
-
这个函数有两个参数列表:
- 第一个参数列表:
(name: String),显式传入用户名。 - 第二个参数列表:
(implicit password: String = "123456"),implicit表示这是一个隐式参数。
- 第一个参数列表:
-
隐式参数可以有默认值,这里默认值是
"123456"。 -
如果调用时没有显式传值,Scala 会:
- 先找作用域中的隐式值(
defaultPassword)。 - 如果找不到,再使用默认值。
- 先找作用域中的隐式值(
3. main 方法调用
scala
def main(args: Array[String]): Unit = {
reg("小花")
reg("小明")("admin")
}
3.1 reg("小花")
-
只传了第一个参数列表的
name("小花")。 -
第二个参数列表没有传值,Scala 会:
- 先找作用域中的隐式值:
defaultPassword→"88888888"。 - 因为找到了,就使用这个值。
- 先找作用域中的隐式值:
-
输出:
plaintext
用户名:小花, 密码: 88888888
3.2 reg("小明")("admin")
-
第一个参数列表传了
name("小明")。 -
第二个参数列表显式传了
"admin",所以不会使用隐式值或默认值。 -
输出:
plaintext
用户名:小明, 密码: admin
4. 运行结果示例
plaintext
用户名:小花, 密码: 88888888
用户名:小明, 密码: admin
5. 总结
-
隐式参数:用
implicit修饰的参数,可以在调用时省略,由 Scala 自动查找作用域中的隐式值填充。 -
隐式值:用
implicit val定义的常量,用于给隐式参数传值。 -
默认值:隐式参数可以有默认值,如果找不到隐式值,就用默认值。
-
隐式参数的匹配规则:类型匹配(这里是
String)。 -
隐式参数常用于:
- 配置信息(如默认密码、默认时区)。
- 依赖注入。
- 上下文信息传递。