当前位置: 首页 > 知识库问答 >
问题:

这个case类定义如何允许中缀模式匹配?

刘胜泫
2023-03-14
/** A wrapper over sequence of matches.
   *
   *  Given `p1: Parser[A]` and `p2: Parser[B]`, a parser composed with
   *  `p1 ~ p2` will have type `Parser[~[A, B]]`. The successful result
   *  of the parser can be extracted from this case class.
   *
   *  It also enables pattern matching, so something like this is possible:
   *
   *  {{{
   *  def concat(p1: Parser[String], p2: Parser[String]): Parser[String] =
   *    p1 ~ p2 ^^ { case a ~ b => a + b }
   *  }}}
   */
  case class ~[+a, +b](_1: a, _2: b) {
    override def toString = "("+ _1 +"~"+ _2 +")"
  }

假定上述代码当然是可能的,并且使用a~b定义的解析器可以通过{case a~b=>...}提取到值中,那么这种非应用程序的工作原理到底是什么?我知道scala中的unapply方法,但这里没有提供。案例类是否默认提供一个(我想是的)?如果是这样,这个特殊的case类如何变成caseA~b而不是case~(a,b)?这是scala程序员可以利用的模式吗?

这与这个问题中带有unapply的对象不同,因为不存在unapply方法--或者是否存在?case类会自动神奇地接收unapply方法吗?

共有1个答案

子车成和
2023-03-14

case类是否默认提供[unapply](我想是的)?

你的怀疑是对的。unapply()是case类中自动提供的许多内容之一。您可以通过执行以下操作来自己验证这一点:

  1. 在自己的文件中编写一个简单的定义。
  2. 只通过“typer”阶段编译文件并保存结果。(调用scalac-xshow-phase查看所有编译器阶段的说明。)
  3. 编辑文件。在类定义前添加单词case
  4. 重复步骤2。
  5. 比较两个保存的结果。
%%> cat srcfile.scala
class XYZ(arg :Int)
%%> scalac -Xprint:4 srcfile.scala > plainClass.phase4
%%> vi srcfile.scala  # add “case” 
%%> scalac -Xprint:4 srcfile.scala > caseClass.phase4
%%> diff plainClass.phase4 caseClass.phase4
  • productserializable混合到类型中
  • 提供对构造函数参数的公共访问
  • 有方法copy()productarityproductelement()canequal()
  • 重写(为)方法ProductPrefixProductIteratorHashcode()ToString()Equals()
  • 提供新代码

伴生对象(由编译器创建)

  • 有方法apply()unapply()
  • 重写tostring()

如果是这样,这个特殊的case类如何变成caseA~b而不是case~(a,b)

这被证明是语言提供的一个很好的(如果相当模糊的话)便利。

unapply()调用返回一个元组,可以将其模式化为中缀符号。同样,这很容易验证。

class XX(val c:Char, val n:Int)
object XX {
  def unapply(arg: XX): Option[(Char, Int)] = Some((arg.c,arg.n))
}

val a XX b = new XX('g', 9)
//a: Char = g
//b: Int = 9
 类似资料:
  • 使用下面的配置,我必须将“.html”附加到任何URL模式,以便将其映射到适当的控制器。如何将Thymeleaf配置为也允许模式,例如,而不仅仅是?

  • 这与JAXB生成的No@XmlRootElement等问题的方向相反。基本上,我想运行schemagen并拥有两个相同类型的全局元素。 我了解如何使用JAXBElement列表事物,但我不知道如何正确生成模式。在我看来,它看起来像以下片段(@XmlRootElements是虚构的)。

  • 考虑以下代码: 我得到了错误 on-但我真的希望能够将类型检查移动到此函数中,因为这减少了我必须将类型检查到一个位置的次数。

  • 我有一个正则表达式,允许一个大小写,一个小写,8-16个字符和大多数特殊字符,包括空间。我想在正则表达式中添加允许空间。 我曾经尝试过: > 正则表达式中的空格 Regex允许字母数字、空格和一些特殊字符 Java空间和换行正则表达式 我的正则表达式如下: 我只想在这里加一点空间。我试过和

  • 问题内容: 假设在我的Elasticsearch索引中,我有一个名为“点”的字段,其中将包含由标点符号分隔的字符串(例如“ first.second.third”)。 我需要搜索例如“ first.second”,然后获取其“点”字段包含正好是“ first.second”或以“ first.second”开头的字符串的所有条目。 我在理解文本查询的工作方式时遇到问题,至少我无法创建执行此任务的查

  • 我有正则表达式来匹配以下模式, 链接到用例:https://regex101.com/r/wnp1k4/1 如何通过修改正则表达式获得相同的匹配?请帮助。 如果'X或x'在数字之前,订单号不应该被检测到。所以这工作正常。 X123456789 X123456789 x123-456-789 X123-456-789 123-456-789 需要修改正则表达式模式以获得如下所示的医嘱号列表的匹配项…