Scala核心编程(9)-隐式转换和隐式参数及隐式类

隐式转换

式转换函数是以implicit关键字声明的带有单个参数的函数。这种函数将会自动应用,将值从一种类型转换为另一种类

PS:使用隐式函数可以优雅的解决数据类型转换

 案例

将double类型和字符串类型数据转换成Int类型

package com.example

object Main {

  implicit def double2Int(d: Double): Int = {
    println("execute Double to Int.................." + d)
    d.toInt
  }

  implicit def long2Int(d: Long): Int = {
    println("execute Long to Int.................." + d)
    d.toInt + 13
  }

  implicit def string2Int(d: String): Int = {
    println("execute String to Int.................." + d)
    d.length
  }

  def main(args: Array[String]): Unit = {
    val num1: Int = 3.5
    println("Double to Int: " + num1)
    val num2: Int = 20L
    println("Long to Int: " + num2)

    val s1: Int = "aa"
    println("String to Int: " + s1)
    val s2: Int = "abc"
    println("String to Int: " + s2)

  }
}

 执行结果

//Double、Long、String 是输入类型, Int 是转换后的类型

execute Double to Int..................3.5
Double to Int: 3
execute Long to Int..................20
Long to Int: 33
execute String to Int..................aa
String to Int: 2
execute String to Int..................abc
String to Int: 3

 总结

相当于执行前会调用这个隐式转换函数

注意事项 

  •  隐式转换函数的函数名可以是任意的,隐式转换与函数名称无关,只与函数签名(函数参数类型和返回值类型)有
  • 隐式函数可以有多个(即:隐式函数列表),但是需要保证在当前环境下,只有一个隐式函数能被识(如果被识别出来有多个方法可被调用,会因为不确定调用哪个方法而报错)
  • 隐式操作不能嵌套使用

隐式转换的好处

隐式转换可动态的增加功能,比如,现在Human已经具备了说话的能力,如果想要赋予它唱歌的能力的话,改动源码是很难接受的(如果是三方的程序就更难改动),而且也违背了软件开发的OCP开发原则 (开闭原则 open close priceple) ,可以通过隐式转换函数给类动态添加功能

package com.example

object StrongObject {
  // 将human对象变成women对象,增强human对象的功能
  implicit def strongObject(h: Human): Women = {
    println("execute Human to Women..................")
    new Women
  }

  def main(args: Array[String]): Unit = {
    val human = new Human
    human.speak("努力努力再努力")
    human.sing("情书")
  }

  class Human {
    def speak(content: String): Unit = {
      println("人类说话:" + content)
    }
  }

  class Women {
    def sing(content: String): Unit = {
      println("女士唱歌:" + content)
    }
  }
}

执行结果 

人类说话:努力努力再努力
execute Human to Women..................
女士唱歌:情书

 隐式参数

个形参变量标记为implicit,所以编译器会在方法省略隐式参数的情况下去搜索作用域内的隐式值作为缺省参数

案例

package com.example

object ImplicitParam {
  implicit val str: String = "华晨宇"

  def hello(implicit name: String): Unit = {
    println("hello: " + name)
  }

  def main(args: Array[String]): Unit = {
    //如果找到值就去对应的作用域内找隐式参数值
    hello
    //有值的话就使用入参中的值
    hello("关晓彤")

  }
}

执行结果

hello: 华晨宇
hello: 关晓彤

 隐式类

scala2.10后提供了隐式类,可以使用implicit声明类式类的非常强大,同样可以扩展类的功能,比前面使用式转换丰富类库功更加的方便,在集合中隐式类会发挥重要的作用

package com.example

object ImplicitClass {


  def main(args: Array[String]): Unit = {
    implicit class Women(val h: Human) {
      def sing(content: String): Unit = {
        println("女士唱歌:" + content)
      }
    }
    val human = new Human
    human.speak("努力努力在努力")
    human.sing("情书")
  }

  class Human {
    def speak(content: String): Unit = {
      println("人类说话:" + content)
    }
  }
}

 执行结果

人类说话:努力努力在努力
女士唱歌:情书

 隐式类特点

  • 所带的构造参数有且只能有一
  • 式类必须被定义在“类”或“伴生对象”或“包对象”里,即隐式类不能是 级的(top-level  objects)
  • 式类不能是case class
  • 用域内不能有与之相同名称标识

隐式转换的发生时机

  1. 方法中的参数的类型与目标类型不一致
  2. 对象调用所在类中不存在的方法或成员时,编译器会自动将对象进行隐式转换(根据类型
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值