Scala隐式转换

参考《快学Scala》和其他同学的一些博客

隐式转换和隐式参数是Scala的两个重要功能,我们可以利用隐式转换来丰富现有类的功能,以及隐式对象可以自动呼出用于执行转换或其他任务;我们可以提供优雅的类库,对类库的使用者隐藏掉那些枯燥乏味的细节。

scala提供了implicit关键字

一、隐式类

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

1.隐式类小例子:

2.隐式类的限制条件:

(1)只能在别的trait/类/对象内部定义,它不能是一个顶级类

(2)构造函数只能携带一个非隐式参数。

(3)在同一作用域内,不能有任何方法、成员或对象与隐式类同名。

 

二、隐式函数

1.隐式函数是什么?

隐式转换函数是以implicit关键字作用于带有单个参数的函数上。这种函数将会自动应用将值从一种类型转换为另外一种类型。(相当于将一种类通过一种函数变为了另一种类)

例:编写隐式函数支持由Double=>Int的转换

2.隐式函数的注意事项:

(1)隐式转换函数与函数名无关,只与函数签名(函数参数类型,函数的返回值类型)有关。

(2)隐式转换函数可以有多个(隐式转换列表),但是需要保证当前环境下只有一个隐式函数被识别(不要引起歧义)。

例:还是上一个例子(报错)

3.利用隐式转换丰富现有类库的功能

如果需要为一个类动态的添加方法,可以通过隐式转换来实现。

例:在Scala中,可以定义一个经过丰富(定义了想要添加的方法)的类,提供我想要的功能。

class RichFile(val from:File){//定义了想要添加的方法
    def read=Source.fromFile(from.getPath).mkString
}

通过隐式转化可以将原来类型(File)转换到现在的类型(RichFile),使原来的类的对象可以调用read方法

implicit def fileTorichFile(from:File)=new RichFile(from)

4.引入隐式转换的方式:

 

5.隐式转换规则
隐式转换在如下三种各不相同的情况会被考虑:
(1)当表达式的类型与预期的类型不同时
(2)当对象访问一个不存在的成员时(类似于上面丰富类库的情况)
(3)当对象调用某个方法,而该方法的参数声明和传入参数类型不匹配的情况
 

三、隐式值

隐式值也叫隐式变量,将某个形参变量标记为implicit,所以编译器会在方法省略参数的情况下去搜索作用域内的隐式值作为省缺参数
1.小例子:
object demo2 {
  implicit val name:String="Nelson"
  def sayHello(implicit name:String):Unit={
    println("Hello,"+name)
  }
  def main(args: Array[String]): Unit = {
    sayHello
  }
}

2.总结一下隐式值的注意事项:
(1)同时出现隐式值、默认值、传值时,编译器的优先级为:传值 >隐式值>默认值(优先级一定要分清)
(2)隐式匹配时,不能有二义性
(3)如果隐式值、默认值、传值都没有的情况下,使用隐式值的地方便会报错
### Scala 转换机制及其应用 在 Scala 中,转换是一种强大的特性,允许编译器自动将一种类型的对象转换为另一种类型。这种功能通过 `implicit` 关键字来实现。 #### 定义转换函数 转换可以通过定义带有 `implicit` 关键字的方法来完成。当遇到无法匹配参数类型的调用时,编译器会尝试查找适用的转换方法并应用它[^1]。 ```scala // 定义一个简单的转换函数 implicit def intToString(x: Int): String = x.toString ``` 上述代码定义了一个从 `Int` 到 `String` 的转换,在需要字符串的地方可以无缝使用整数变量而无需显的 `.toString()` 转换操作。 #### 使用上下文中的值 除了定义转换规则外,还可以利用已导入的作用域内的值来进行更复杂的逻辑处理或提供默认参数设置[^2]。 ```scala object MathUtil { implicit val defaultPrecision: Double = 0.0001 def approxEquals(a: Double, b: Double)(implicit precision: Double): Boolean = math.abs(a - b) <= precision } ``` 在这个例子中,如果未指定精度,则采用预设好的值作为比较的标准误差范围。 #### 应用于库设计模 Lift Web Framework 就很好地运用了这一概念,比如其 CSS 绑定机制就依赖于视图绑定支持动态页面元素更新而不必每次都手动传递模板片段[^3]。 ```scala class MySnippet { def render = "#someElement *" #> "Hello world" } ``` 这里展示了如何借助 CSS 选择器语法简化 HTML 片段替换过程,并且背后依靠的就是框架内部定义的一系列转换规则使得开发者能够写出更加直观简洁的代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值