【问题标题】:How to case match on a function with optional parameters如何在具有可选参数的函数上进行大小写匹配
【发布时间】:2019-06-20 13:06:45
【问题描述】:

我希望能够有一个带有可选参数的方法。当存在该可选参数时,它将调用特定的数据库查询,该查询返回使用可选参数过滤的记录。如果该可选参数不存在,我希望它调用不按可选参数过滤的不同数据库查询。

第一个查询尚未编写,但将具有相同的返回结构和类型。编写了第二个查询,并且在没有可选参数和案例的情况下可以正常工作。

def getRecords(id: String, type: String = ""): Future[List[Set[String]]] = {
    case Some(type) =>
        val query =>
            s"""
                | ...
             """.stripMargin
    case _ => 
        val query =>
            s"""
                | ...
             """.stripMargin

    record = get(dbResult).asList.asScala.map(_.toString).toSet

}

我收到的错误是

The argument types of an anonymous function must be fully known. (SLS 8.5)
Expected type was: scala.concurrent.Future[List[Set[String]]]
: Future[List[Set[String]]] = {

                              ^

有人可以向我解释错误的含义吗?以及如何设计我的方法以按照我想要的方式工作?

注意:该方法的一些细节已被省略。它本质上只是返回返回类型的记录以及其中一个查询获取的任何数据。

【问题讨论】:

  • def getRecords(id: String, `type`: Option[String] = None): Future[List[Set[String]]] = `type` match { case Some(t) => ...; case _ => ... }。注意t 这里将是你的字符串,如果它存在的话。
  • 一个简单的选择是有两个重载版本的函数,一个有一个参数,一个有两个参数。
  • 正如@Lasf 提到的,type 是反向关键字,您不应该使用它。如果真的需要,那么你可以使用 `
  • @Lasf 你能提供一个答案吗?我不能很好地阅读它。此外,如果它有效(它似乎是答案,如果不是非常接近)我会将其标记为正确。
  • @Tim 感谢您的评论。我可以重载,但是代码库的结构是这样设计的,即我不仅要添加一个方法,而且基本上是方法的两倍,所以我试图在一个中完成它。我可能不应该在我的例子中使用它。在我的实际方法中,它不被称为“类型”。我不得不更改/省略细节。

标签: scala parameters pattern-matching anonymous-function


【解决方案1】:

你的评论,当然,给你:

def getRecords(id: String, `type`: Option[String] = None): Future[List[Set[String]]] = {
  val matchResult = `type` match {
    case Some(t) =>  //t is your string
        val query =
            s"""
                | ...
             """.stripMargin
        //do something with your query val
    case _ => 
        val query =
            s"""
                | ...
             """.stripMargin
        //do something with your query val
  }
  //use your matchResult here, whatever that ends up being
  //not sure how this works but just copied from your question:
  get(dbResult).asList.asScala.map(_.toString).toSet
}

显然,您必须在某处使用query,但我假设您已经简化了它。如果你担心空字符串,你可以在你的第一个 case 子句中添加一个保护:case Some(t) if t.nonEmpty => ...type 被反引号,因为它是一个关键字。如果您使用非关键字名称,则不需要反引号。

【讨论】:

  • 我已经完全按照您在回答中显示的内容完成了。但是,我收到了Type mismatch, found: Unit, required: Future[List[Set[String]]]。知道为什么吗?我输入了两个相同的查询,只是为了确保没有错误。但是,无论case Some(t) 案例中是否存在查询,我都会收到此错误,该错误会一直延伸到 `case None.知道为什么吗?
  • @Chris 你可能需要返回record,在方法的末尾写record,假设它已经是正确的类型。如果get(dbResult).asList.asScala.map(_.toString).toSet 生成正确的类型/返回值,那么您可以将其作为我在回答中所做的最后一行。
  • 如果没有这些情况,record = ... 行会返回正确的类型。我再看看。是否可以在方法定义中不包含匹配项的情况下进行这种模式匹配?
  • @Chris 我编辑了我的答案。见val matchResult。另请记住,您需要使用 val 来声明一个值,例如val record。将其移到匹配块之外。不幸的是,我不太了解您的问题...如果您想匹配方法参数,则需要在该方法的定义中进行匹配。
  • 这似乎成功了。非常感谢您的帮助。另外我不是指方法定义,我只是指方法名称和参数(我认为是方法头?)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-11
  • 2012-12-19
  • 2015-09-12
  • 2013-04-19
相关资源
最近更新 更多