Scala隐式函数、隐式方法以及隐式类

本文深入探讨Scala中的隐式参数、隐式函数及隐式类的功能与应用。通过实例介绍了如何利用隐式转换来简化类型转换操作,以及如何定义和使用隐式参数以增强函数的灵活性。

Scala隐式函数、隐式方法以及隐式类

Scala中提供了隐式转换和隐式参数等独特的功能,这些是JAVA中所没有的。它支持手动将某种类型对象转换成其他类型,某些场景下非常有用。Scala隐式转换的核心是隐式转换函数(implicit-conversion-function)。定义隐式转换函数,只需要在编写的程序单元内引入,Scala就会自动调用并根据函数签名,在运行中涉及到参数类型相关的对象时,自动转换为指定类型。隐式转换函数对名称没有强制要求。一般建议将这类函数命名为“type2type”的形式。隐式转换函数与普通函数在语法上的差别是以implicit开头,并且需要定义函数返回类型。

先写一个空的scala对象,以及其伴生类:

class FunctionDemo

object FunctionDemo {

}

下面我们将开始了解什么是scala中的隐式参数,隐式函数和隐式类

隐式参数

class FunctionDemo

object FunctionDemo {
  //隐式参数
  implicit var d=4
  
  def fun(a:Int)(b:Int)(c:Int)(implicit d:Int):Int={
        a+b+c+d
    }
    println(fun(1)(2)(3))//结果为:10
}

这里可以看到:在调用fun函数时,只输入了前三个参数,最后一个参数d是自动调用前面定义的
implicit var d=4
这就是隐式参数。

隐式函数和隐式类

重新定义一个新的对象:

object ImplicitCase {
  //隐式参数
  implicit var d=4

  //隐式方法
  implicit def doubleToInt(a:Double)=a.toInt
  implicit def doubleToString(a:Double)=a.toString

  //隐式类
  implicit class getJi(obj:FunctionDemo){
    //隐式函数
    def ji(n1:Int,n2:Int):Int={
      n1*n2
    }
  }
}

以上是定义在ImplicitCase类中的一些隐式方法和一个隐式类,把前面的一个隐式参数也放到这个类里,然后使用import导入

import ImplicitCase._

class FunctionDemo

object FunctionDemo {
  def main(args: Array[String]): Unit = {
    import kb11.ImplicitCase._
    def fun(a:Int)(b:Int)(c:Int)(implicit d:Int):Int={
        a+b+c+d
    }

    println(fun(1)(2)(3))  //结果为:10

    val a:Int=3.444   //调用ImplicitCase中的隐式方法使Double转为Int
    println(a)  //结果为:3

    val b:String=4.5555   //调用ImplicitCase中的隐式方法使Double转为String
    println(b)  //结果为:4.5555

    val fd=new FunctionDemo   //创建FunctionDemo类
    val num=fd.ji(4,5)    //调用ImplicitCase中的隐式类的ji方法
    println(num)   //结果为:20
  }
}

Scala转换是一种强大的语言特性,可让编译器在编译期间自动推导信息,从而减少代码量,让程序员省去复杂重复的代码,忽略冗长、过于细节的部分[^1]。以下为几种常见的Scala转换及使用方法: ### 函数 函数使用`implicit`关键字定义,编译器会在需要时自动调用,从而将一种型转换为另一种型。 ```scala // 定义函数 implicit def intToDouble(x: Int): Double = x.toDouble // 使用转换 val num: Double = 5 ``` ### 参数 在函数方法中定义用`implicit`修饰的参数,Scala会尝试找到指定型且用`implicit`修饰的对象(即值)并注入参数。查找位置为当前作用域内可见的`val`或`var`定义的变量,以及参数型的伴生对象内的值。 ```scala object ImplicitOps3 { def main(args: Array[String]): Unit = { var myArray: Array[Int] = Array(5, 6, 45, 1, 8, 9, 25, 0, 4, 91) println("排序前:" + myArray.mkString("[", ",", "]")) var newArray = myArray.sortWith(_ < _) println("排序后:" + newArray.mkString("[", ",", "]")) implicit val ord = new Ordering[Int]() { override def compare(x: Int, y: Int): Int = y.compareTo(x) } newArray = myArray.sorted println("排序后:" + newArray.mkString("[", ",", "]")) } } ``` ### Scala 2.10 之后引入了,使用`implicit`声明可扩展的功能。所带的构造参数有且只能有一个,且必须被定义在“”或“伴生对象”或“包对象”里。 ```scala object TestImplicitClass { implicit class MyRichInt(val self: Int) { def myMax(num: Int): Int = if (num > self) num else self def myMin(num: Int): Int = if (num > self) self else num } def main(args: Array[String]): Unit = { println(12.myMax(15)) println(12.myMin(15)) } } ``` ### 解析机制 首先会在当前代码作用域下查找实体(方法对象),若查找失败,会继续在参数的型的作用域里查找,型的作用域指与该型相关联的全部伴生对象以及该型所在包的包对象[^3]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值