Scala for 循环中缺失值

问题描述 投票:0回答:1

我需要为学校的 scala3 中的 find 命令编写一个 CLI。语法是:

run [path] [--filterName filterParameter]
。我目前让它一次对一个过滤器起作用,但是一旦它尝试使用两个或多个过滤器的命令,只有最后一个生效。

例如,如果我运行:

run src/ --name main
,我会得到输出
src/main
src/main/scala/find/cli/main.scala
,这是正确的。

如果我运行:

run src/ --type scala
我会正确获取所有 scala 文件。

但是如果我运行:

run src/ --name main --type scala
,而不是得到
src/main/scala/find/cli/main.scala
,我会得到与运行
run src/ --type scala
相同的输出。如果我反转过滤器,那么运行:
run src/ --type scala --name main
我得到与运行相同的输出:
run src/ --name main

cli.scala:

package find
package cli

import scala.collection.mutable
import scala.util.matching.Regex

val usageMap: mutable.LinkedHashMap[String, String] = mutable.LinkedHashMap(
  "name" -> "[--name X] (where X is a string)",
  "type" -> "[--type X] (where X is a string)",
)

var path = ""
var file: cs214.Entry = cs214.MockFile("zef", None, 2)

var failMsg = ""

/** Command-line interface for the `find` program.
  *
  * Note: this function is provided to you and you do not need to understand how
  * it works yet.
  *
  * @param args
  *   the command-line arguments.
  */
@main def cs214find(args: String*) = entryPoint(args)(cs214.open)

def entryPoint(args: Seq[String])(open: String => cs214.Entry): Boolean =
  if args.length < 1 then
    return fail("No path argument given.")

  path = args.head

  path match
    case "--help" => false
    case _ => 
        file =
        try
            open(path)
        catch
            case _: java.nio.file.NoSuchFileException =>
                return fail(createFailMsg(error = f"Path '$path' does not exist."))
            case e: Exception =>
                return fail(createFailMsg(error = f"Open raised an exception: ${e.getMessage}."))

        var results: List[List[String]] = List()
        var filters = args.mkString(" ").split("--")
        filters(0) = filters(0).replaceAll(path + " ", "")
      
        for filter <- filters yield
            getFilterCondition(filter) match
                case Nil => None
                case l => results = l :: results

        if failMsg.nonEmpty then fail(failMsg)
        else if results.length == 1 then
            showResults(results.head)
            true
        else
            results.foreach(showResults)
            true

def showResults(res: List[String]) =
  for f <- res yield println(f)
      
def getFilterCondition(filter: String): List[String] =
  filter match
    case s"name $name" => find(file, (entry: cs214.Entry) => (entry.isDirectory() && entry.name() == name) || (!entry.isDirectory() && entry.name().split("\\.").head == name))
    case s"type $extension" => find(file, (entry: cs214.Entry) => !entry.isDirectory() && entry.name().split("\\.")(1) == `extension`)
    case filter => List()

def createFailMsg(error: String = "", filter: String = ""): String =
  f"Error: $error\nUsage: ${usageMap(filter)}"

def fail(msg: String): Boolean =
  System.err.println(msg)
  false

find.scala:

package find

def find(entry: cs214.Entry, f: cs214.Entry => Boolean): List[String] =
  var res: List[String] = List()
  if f(entry) then res = List(entry.path())
  if entry.isDirectory() && entry.hasChildren() then res = find(entry.firstChild(), f) ::: res
  if entry.hasNextSibling() then res = find(entry.nextSibling(), f) ::: res
  res.reverse

结果似乎在 cli.scala 中丢失了:

for filter <- filters yield
  getFilterCondition(filter) match  <-- results lost
    case Nil => None
  case l => results = l :: results

我不明白如何以及为什么。

任何帮助将不胜感激。

P.S: 有些部分没有完成,比如非过滤器和深度搜索的实现,这是正常的。

scala anonymous-function higher-order-functions scala-3 for-comprehension
1个回答
0
投票

这对我来说是一个愚蠢的错误,但我需要像这样调用 getFilterCondition:

getFilterCondition(filter.trim())
而不是
getFilterCondition(filter)

© www.soinside.com 2019 - 2024. All rights reserved.