【问题标题】:Matching on class members "error: not found: value &&"匹配类成员“错误:未找到:值 &&”
【发布时间】:2013-06-10 23:27:19
【问题描述】:

我正在尝试从 Twitter Scala School 开始学习 Scala,但遇到语法错误。当我通过我的 sbt 控制台运行“基础知识继续”教程http://twitter.github.io/scala_school/basics2.html#match 中的模式匹配代码时,编译器将我返回为“错误:未找到:值 &&”。 Scala 中是否发生了一些变化,以采用在编写教程时可能起作用但现在不起作用的东西?所涉及的类是

class Calculator(pBrand: String, pModel: String) {
  /**
   * A constructor
   */
  val brand: String = pBrand
  val model: String = pModel
  val color: String = if (brand.toUpperCase == "TI") {
    "blue"
  } else if (brand.toUpperCase == "HP") {
    "black"
  } else {
    "white"
  }

  // An instance method
  def add(m: Int, n: Int): Int = m + n
}

class ScientificCalculator(pBrand: String, pModel: String) extends Calculator(pBrand: String, pModel: String) {
  def log(m: Double, base: Double) = math.log(m) / math.log(base)
}

class EvenMoreScientificCalculator(pBrand: String, pModel: String) extends ScientificCalculator(pBrand: String, pModel: String) {
  def log(m: Int): Double = log(m, math.exp(1))
}

我的 repl 看起来像这样......

bobk-mbp:Scala_School bobk$ sbt console
[info] Set current project to default-b805b6 (in build file:/Users/bobk/work/_workspace/Scala_School/)
[info] Starting scala interpreter...
[info] 
Welcome to Scala version 2.9.2 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_17).
Type in expressions to have them evaluated.
Type :help for more information.
...
scala> def calcType(calc: Calculator) = calc match {
     |   case calc.brand == "hp" && calc.model == "20B" => "financial"
     |   case calc.brand == "hp" && calc.model == "48G" => "scientific"
     |   case calc.brand == "hp" && calc.model == "30B" => "business"
     |   case _ => "unknown"
     | }
<console>:9: error: not found: value &&
         case calc.brand == "hp" && calc.model == "20B" => "financial"
                                 ^
<console>:10: error: not found: value &&
         case calc.brand == "hp" && calc.model == "48G" => "scientific"
                                 ^
<console>:11: error: not found: value &&
         case calc.brand == "hp" && calc.model == "30B" => "business"
                                 ^
scala> 

当我对类成员进行匹配时,如何在我的案例中获取 AND 的用例?

提前致谢。我是新手。

【问题讨论】:

  • 顺便说一句,您使用的是过时的 Scala 版本。当前版本是2.10.2
  • 当我强制 SBT 控制台使用更新版本的 Scala 时,结果是一样的。
  • 是的,当然,但是过时的版本就是过时的版本......

标签: scala


【解决方案1】:

如果您按值匹配,就像您的情况一样,您不仅可以使用警卫,还可以坚持使用普通模式匹配:

def calcType(calc: Calculator) = (calc.brand, calc.model)  match {
     case ("hp", "20B") => "financial"
     case ("hp", "48G") => "scientific"
     case ("hp", "30B") => "business"
     case _             => "unknown"
}

我发现这个更容易解析。

【讨论】:

  • 这就是我要说的!太糟糕了,我无法撤消正确答案检查,因为我认为这个版本准确地抓住了案例的精神。究竟发生了什么?您的函数将 Calculator 中的品牌和型号值转换为元组并发送该孩子通过匹配?
  • 是的,这里发生的是匹配元组。此外,如果 Calculator 是一个案例类,您可以编写类似 calc match { case Calculator("hp", "20B") =&gt; "financial" .... 的内容。 (无耻插件——其实你可以撤消)
  • @BobKuhar:可以撤消正确答案。只需将另一个标记为正确的...
【解决方案2】:

当您想使用模式测试条件时,您需要使用guard

calc match {
  case _ if calc.brand == "hp" && calc.model == "20B" => "financial"
  ...
}

_ 表示您不关心calc 具有的具体值,而是守卫中提到的其他一些条件。

顺便说一句,可以写conjunction extractor

object && {
  def unapply[A](a: A) = Some((a, a))
}

但它不适用于您的具体情况。

【讨论】:

  • 嗯。所以 twitter 文档的东西不能像写的那样工作?在我从中提取代码的部分之前,它们非常简要地介绍了“守卫”。看起来这是一个已知问题:github.com/twitter/scala_school/pull/89
  • 就是这样!但是很时髦。 “捕获” _ 的需要对我来说似乎是多余的。不管。它编译了,我对“新闪亮”的理解有所提高。
猜你喜欢
  • 2014-08-02
  • 2021-08-27
  • 1970-01-01
  • 2012-07-05
  • 1970-01-01
  • 1970-01-01
  • 2021-08-18
  • 2016-07-07
  • 1970-01-01
相关资源
最近更新 更多