Scala隐式转换

本文介绍了Scala中的隐式转换,包括隐式转换函数、隐式类、隐式参数和隐式值。这些转换用于增强类的功能,使静态类型动态化。Scala 2.10以后推荐使用隐式类,因为它们提高了代码的可读性。文章详细阐述了各种隐式转换的规则和用法,并提供了示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

隐式转换是Scala的强大特性之一,使得静态类型动态化,可以动态为现有类库添加定制化的功能。

隐式转换分四种

  • 隐式转换函数
  • 隐式类
  • 隐式参数
  • 隐式值

隐式转换的规则

  1. 如果代码无需隐式转换即可通过编译,则不会引入隐式转换,即便引入了也不会起作用(idea中显示为灰色);
  2. 不可存在二义性,如存在两个相同类型的隐式值时编译会报错
  3. 隐式操作不能嵌套使用(如 convert1(convert1(x)) ),即隐式转换从源类型到目标类型只会经过一次转换,不能经过多次隐式转换达到目标;
  4. 作用域原则,只在当前引入隐式转换的作用域内才起作用

使用方式:将对应的函数、类、参数、值标记为implicit

1、隐式转换函数

作用:增强一个类,添加本不存在的方法函数

格式:

隐式函数

1

2

3

implicit def 函数名(参数):返回值类型={

     //函数体

}

例1:

隐式函数例1

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

package lzr.implicitTest

 

/**

  * Created by lizhirong on 2018/8/28.

  */

 

//Mathematics仅仅提供add函数 

class Mathematics {

  def add(x: Int, y: Int): Int = {

    x + y

  }

}

 

//下面是增强Mathematics类,添加一个subtract方法

class RichMathematics(val mathematics: Mathematics) {

  def substract(x: Int, y: Int) = {

    x - y

  }

}

 

object ImplicitFunctionTest {

  //将Mathematics转换为RichMathematics

  //Mathematics对象上可以直接调用RichMathematics定义的方法 

  implicit def mathematicsToRichMathematics(mathematics: Mathematics) = {

    new RichMathematics(mathematics)

  }

 

//  implicit def mathematicsToRichMathematics2(mathematics: Mathematics) = {

//    new RichMathematics(mathematics)

//  }

 

  def main(args: Array[String]) {

    val = new Mathematics

    println(m.add(207))

    println(m.substract(207)) //substract不属于 Mathematics,但可以使用

  }

 

}

隐式转换函数的规则:

  • 隐式转换函数的函数名可以是任意的,与函数名称无关,只与函数签名(函数参数和返回值类型)有关。
  • 如果当前作用域中存在函数签名相同但函数名称不同的两个隐式转换函数(本例中的mathematicsToRichMathematics和mathematicsToRichMathematics2),则在进行隐式转换时会报错,即隐式转换的规则2

 2、隐式类

在scala2.10后提供了隐式类,可以使用implicit声明类,相对于隐式函数更容易理解,代码更直观易懂

作用:增强对应的类

格式:

隐式转换

1

2

3

implicit class 类名(参数){

    //类主体

}

例2:

隐式转换

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

package lzr.implicitTest

 

/**

  * Created by lizhirong on 2018/8/28.

  */

 

//Mathematics仅仅提供add函数 

class Mathematics2 {

  def add(x: Int, y: Int): Int = {

    x + y

  }

}

 

object ImplicitClassTest {

  def main(args: Array[String]) {

    val = new Mathematics2

    println(m.add(207))

    println(m.substract(207)) //substract不属于 Mathematics,但可以使用

  }

   

  //下面是隐式类的方式,给Mathematics类添加一个subtract方法

  implicit class RichMathematics(val mathematics: Mathematics2) {

    def substract(x: Int, y: Int) = {

      x - y

    }

  }

}

 

隐式类的规则

  • 隐式类的主构造函数的参数有且仅有一个,是因为隐式转换是将一种类型转换为另外一种类型,源类型与目标类型是一一对应的
  • 隐式类构造器只能带一个不是implicit修饰的参数
  • 必须定义在另一个class/object/trait里面(不能独立定义)

     

 3、隐式参数

格式:

隐式转换

1

2

3

def 函数名(implicit 参数名:类型):返回值={

       //函数体

}

例3:

隐式转换

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

package lzr.implicitTest

 

/**

  * Created by lizhirong on 2018/8/28.

  */

 

class Mathematics3 {

  //柯里化,隐式参数要么只有一个,要么使用柯里化(柯里化时只能最后一个参数使用隐式implicit)

//  def add1(x: Int, implicit y: Int): Int = {

//    x + y

//  }

//  def add2(implicit x: Int)(y: Int): Int = {

//    x + y

//  }

  def add(x: Int)(implicit y: Int = 0): Int = {

    x + y

  }

  def power(implicit y: Int): Int = {

    y * y

  }

}

 

object ImplicitParamTest {

  def main(args: Array[String]) {

    val = new Mathematics3

    println(m.add(20)(7))

    println(m.add(20))

    println(m.power(7))

  }

}

隐式参数的规则:

  1. 隐式参数要么指定全部参数,要么使用柯里化(柯里化时只能最后一个柯里化内的参数(可多个)使用隐式implicit)
  2. implicit关键字在作用域内只能出现一次
  3. 匿名函数不能使用隐式参数

 4、隐式值

格式:

隐式转换

1

implicit val 变量名:类型=

例4:

隐式转换

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

package lzr.implicitTest

 

/**

  * Created by lizhirong on 2018/8/28.

  */

 

object ImplicitValueTest {

  implicit val y: Int = 2

  implicit val z: Double = 4

  def add(x: Int)(implicit y: Int = 0): Int = {

    x + y

  }

  def power(x: Int)(implicit y: Double): Double = {

    x * y

  }

  def main(args: Array[String]) {

    println(add(20))

    println(power(2))

  }

}

隐式值的规则:

  1. 相同类型的隐式值只能有一个

 

注:scala-2.10之后,推荐使用隐式类来给增强类的相关函数功能,相较于之前的隐式函数更容易理解,代码可阅读性更高

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值