Scala隐式课程

时间:2017-06-24 15:38:57

标签: scala

根据文档https://users.scala-lang.org/t/sip-13-implicit-classes-scala-documentation/705,隐式类的用例是
“提出了一种新的语言结构来简化类的创建,这些类为另一种类型提供了扩展方法。”
这需要创建新类,相应的功能和导入。
通过使用静态方法创建Utils类可以实现相同的目的。我无法理解隐式类在这里添加的额外好处,这是使用静态方法的Utils类无法实现的。

3 个答案:

答案 0 :(得分:4)

你本身并没有获得任何“权力”,能够做一些你以前做不到的事情;但是隐式类在Utils类中提供了一些静态方法, clear

假设您要执行某些操作,例如检查字符串是否包含多个不同选项中的至少一个。您可以像这样实现此功能:

object Hello {

    def main(args: Array[String]): Unit = {

        val str =
            """
              |Hello Mary,
              |
              |How's it going? I hope everything is going well with you.
              |
              |Bye!
            """.stripMargin

        println( StrUtils.containsOneOf(str,"Good","well","once","later"))
    }

}

object StrUtils {

    def containsOneOf(stringToCheck: String,strings: String*): Boolean = {
        strings.exists(stringToCheck.contains(_))
    }
}

哪个会起作用,但它看起来有点笨重。如果我们使用隐式类,我们可以看起来这个功能一直是String类的一部分。

object Hello {

    def main(args: Array[String]): Unit = {

        val str =
            """
              |Hello Mary,
              |
              |How's it going? I hope everything is going well with you.
              |
              |Bye!
            """.stripMargin

        println( str.containsOneOf("Good","well","once","later"))
    }

    implicit class StringUtils(s: String) {
        def containsOneOf(strings: String*): Boolean = {
            strings.exists(s.contains(_))
        }
    }

}

我相信第二个例子更加清晰,一旦你开始构建复杂的表达式,这种语法确实可以提供帮助。

旁注

由于(几乎)所有编程语言都是图灵完整的,这意味着它们可用于计算图灵机所能提供的任何东西,因此它们在某种意义上“同样强大”。那么,鉴于我们的语言同样强大,我们应该判断一种编程语言吗? 实际上,我认为编程语言有多好的主要指标之一是它能够在复杂性增加时保持易读性。没有明确的可以组合的特征的正交基础的语言往往最终会有大的定义(即大量的边缘情况),最终会让人更加困惑。

此功能的隐式类主要好处是帮助我们保持代码的易读性。

答案 1 :(得分:1)

一个具体的好处:

foo.bar().aMethodAddedByImplicitClass().baz()

使操作顺序比使用静态方法的等效操作更清晰:

UtilsClass.aMethod(foo.bar()).baz()

答案 2 :(得分:0)

我会假设您的问题与隐式案例类特别相关。

隐式案例类使用您喜欢或喜欢使用的语法扩展您的DSL,即:

case class Rectangle(w: Int, h : Int)

implicit class RectangleMaker(w : Int) {
  def x(h: Int) = Rectangle(w, h)
}

val myRec = 3 x 4

编译器将在场景后为您生成的代码:

implicit def RectangleMaker(w: Int) = new RectangleMaker(w)

书中的例子:Scala编程(第3版)。

希望有所帮助,