我偶然发现了这个线程,@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
}
但问题仍然存在——如何向对象添加扩展方法?
隐式类是向对象添加扩展方法的正确方法
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
时,它也不检查扩展方法