Scala – 向Int添加unapply
发布时间:2020-12-16 08:53:33 所属栏目:安全 来源:网络整理
导读:我希望能够做到这一点: scala val Int(i) = "1"i: Int = 1 但Int没有一个不适用的方法. 我找到了this answer,它提供了如何隐式地将方法添加到现有对象的说明,所以我试了一下.他们给出的解决方案有效,但遗憾的是不适用于模式匹配.这就是我所拥有的: object
我希望能够做到这一点:
scala> val Int(i) = "1" i: Int = 1 但Int没有一个不适用的方法. 我找到了this answer,它提供了如何隐式地将方法添加到现有对象的说明,所以我试了一下.他们给出的解决方案有效,但遗憾的是不适用于模式匹配.这就是我所拥有的: object UnapplyInt { val IntRE = """^(d+)$""".r def unapply(v: String): Option[Int] = v match { case IntRE(s) => Some(s.toInt) case _ => None } } implicit def int2unapplyInt(objA: Int.type) = UnapplyInt 这些测试用例都很好: val UnapplyInt(i) = "1" // pattern matching with unapply is fine val i = Int.unapply("1").get // implicit conversion is fine 但我想要的那个失败了: scala> val Int(i) = "1" <console>:10: error: object Int is not a case class constructor,nor does it have an unapply/unapplySeq method val Int(i) = "1" ^ 如果隐式转换工作和与unapply的模式匹配有效,为什么Scala不将这两个东西放在一起用于隐式模式匹配? 解决方法
编辑所以我原来的推理并不好.真正的原因是从
Section 8.1.8 of the Scala language spec
Syntax: SimplePattern ::= StableId ‘(’ [Patterns] ‘)’ 也就是说,提取器对象必须是稳定的,并且隐式转换不稳定.没有解释为什么提取器必须稳定;我怀疑这是因为Scala不想将提取器视为表达式,因为这很快就会变得模棱两可: ... match { foo(bar)(baz) } 现在哪个是构造函数,哪个是模式变量? 幸运的是,你可以做到这一点并且工作正常(但是,正如你评论的那样,引入了其他问题): object Int { def unapply(v: String) = try Some(v.toInt) catch { case _: NumberFormatException => None } } val Int(i) = "5" 因为Int类型和对象Int位于不同的名称空间中. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |