zoukankan      html  css  js  c++  java
  • Scala 进阶(2)—— implicit 用法:隐式转换

    1. 转换接收端

    在 Scala 中,implicit 的一个常见用法,是作为方法调用的接收端,如果觉得这种说法过于晦涩的话,我的理解是:

    • implicit 可以动态地为目标对象增加函数。

    我们首先看一段例子:

      implicit class JsonPatchExt(underlying: playJson.JsonPatch) {
    
        /**
         * Transforms a playJsonPatch [[playJson.JsonPatch]] into a common [[Patch]] used in this project.
         *
         * @return a list of [[Patch]]es representing the list of diffson operations.
         */
        def toCommonPatch: Seq[Patch] = underlying.ops.collect {
          case Add(path, value) => Patch.add(path.serialize, Some(value))
          case Replace(path, value, _) => Patch.replace(path.serialize, Some(value))
          case Remove(path, _) => Patch.remove(path.serialize)
        }
      }

    这里我们定义了一个 implicit class。

    在原先的 source code 中,playJson.JsonPatch 这个类,并没有定义 toCommonPatch 这个方法,而我们通过 implicit class 为 JsonPatch 增加了 toCommonPatch 方法。

    2. 原理

    它是怎么做到的?

    假设现在有个调用端,有一个 jsPatch 的 JsonPatch 对象,用了 jsPatch.toCommonPatch 方法。

    在 Scala 的编译过程中,编译器依次做了以下这些事情:

    1. 根据方法签名,在 JsonPatch 类中寻找一个 toCommonPatch 方法,并且接受空的参数列表,失败。
    2. 寻找一个潜在的,作用域中拥有从 JsonPatch -> XXX 类的隐式转换,并且这个 XXX 类具有需要的方法签名,找到了 JsonPatchExt 类。
    3. 进行一次类型转换,将目标对象 jsPatch 转为相应的 JsonPatchExt 对象,调用其 toCommonPatch 方法,类似于:transform(jsPatch).toCommonPatch,当然,transform 的实现被编译器隐藏了。

    3. 个人习惯/代码规范

    针对这种 implicit class 的定义,一般来说,我个人习惯遵循以下两个原则:

    • 根据适用的作用域,定义在 伴生对象 object 内部,或者 package object 中。
    • 类名一般定义为 XxxExt 或者 RichXxx。
  • 相关阅读:
    django之admin管理工具
    django之中间件
    cookie和session
    day052-53 django框架
    day050 前端Jquery库的使用
    sprint
    Scrum 项目1.0
    【团队项目】3.0
    [读书笔记]
    【团队项目】2.0
  • 原文地址:https://www.cnblogs.com/jing-an-feng-shao/p/14790305.html
Copyright © 2011-2022 走看看