🤖

Scala3(Dotty): さようならimplicit class, こんにちはExtension methods

2021/05/16に公開

Scala3がリリースされました! Scala3 BooksのExtension methodsの例です。

Scala2以降では、Implicit classesを使って、既存の型の拡張(メソッドを後から生やす)ということを行っていました。拡張時には、class名を付けなければいけなかったり、ちょっと大掛かりでした。Scala3でも、implicit classesの構文は使えます。

@main def main: Unit =
  println("1".makeInt(2))   // 1
  println("10".makeInt(2))  // 2
  println("100".makeInt(2)) // 4

implicit class RichString(val s: String) {
  def makeInt(radix: Int): Int = Integer.parseInt(s, radix)
}

Scala3からは、Extenstion Methodsでとてもシンプルに記述できるようになりました。

@main def main: Unit =
  println("1".makeInt(2))   // 1
  println("10".makeInt(2))  // 2
  println("100".makeInt(2)) // 4

extension (s: String)
  def makeInt(radix: Int): Int = Integer.parseInt(s, radix)

次のようにobjectpackage objectで包んだりして使ったりする運用ができます。

import StringExtenstion._

@main def main: Unit =
  println("1".makeInt(2))   // 1
  println("10".makeInt(2))  // 2
  println("100".makeInt(2)) // 4


object StringExtenstion {
  extension (s: String)
    def makeInt(radix: Int): Int = Integer.parseInt(s, radix)
}

次のような意地悪をすると、

@main def main: Unit =
  println("1".makeInt(2))   // 1
  println("10".makeInt(2))  // 2
  println("100".makeInt(2)) // 4


extension (s: String)
  def makeInt(radix: Int): Int = Integer.parseInt(s, radix)

extension (s: String)
  def makeInt(radix: Int): Int = Integer.parseInt(s, radix)

エラーが親切に出て来ました。

Discussion