如何在 Scala 2 中为单例对象添加扩展方法?

问题描述 投票:0回答:1

我偶然发现了这个线程,@prolativ 提供了一些花哨的 scala 3 语法来为对象创建扩展方法

extension (int: Int.type)
  def unapply(s: String): Option[Int] = s.toIntOption

但这让我开始思考是否有办法在 Scala 2 中做类似的事情?

我试过了

implicit class IntOps(s: Int.type) {
  def unapply(s: String): Option[Int] = s.toIntOption
}

这似乎只是 scala 2 翻译,但它不会编译错误

object Int is not a case class, nor does it have a valid unapply/unapplySeq member
.

UPD 在模式匹配的情况下,有一种方法可以做到这一点 - 只需添加新对象并匹配它:

object IntOps {
  def unapply(s: String): Option[Int] = s.toIntOption
}

但问题仍然存在——如何向对象添加扩展方法?

scala object pattern-matching extension-methods implicit
1个回答
0
投票

隐式类是向对象添加扩展方法的正确方法

implicit class IntOps(obj: Int.type) {
  def parse(s: String): Option[Int] = s.toIntOption
}

Int.parse("123") // Some(123)

unapply
可以用同样的方式添加

implicit class IntOps(obj: Int.type) {
  def unapply(s: String): Option[Int] = s.toIntOption
}

Int.unapply("123") // Some(123)

只是这个不会影响模式匹配

"123" match {
  case Int(i) => ??? // doesn't compile: object Int is not a case class, nor does it have a valid unapply/unapplySeq member
}

Scala 2编译器抛出

object Int is not a case class, nor does it have a valid unapply/unapplySeq member
的地方在这里: https://github.com/scala/scala/blob/v2.13.10/src/compiler/scala/tools/nsc/typechecker/PatternTypers.scala#L121-L122

else if (!reallyExists(member))
  CaseClassConstructorError(fun, s"${fun.symbol} is not a case class, nor does it have a valid unapply/unapplySeq member")

这里不检查隐式转换(扩展方法)。

顺便说一句,当编译器决定是否在案例类的伴随对象中生成

unapply
时,它也不检查扩展方法

如何查看Scala自动生成案例类apply函数的代码?


如何扩展 String 以添加新的 unapply 函数以在提取中使用它?

使用未应用的功能丰富 PartialFunction

© www.soinside.com 2019 - 2024. All rights reserved.