Scala本地回归?

wok*_*oky 4 controls closures scala

我刚刚发现return以下闭包中的s将从函数返回findPackage

def findPackage(name: String, suffix: Option[String] = None): Path = {
    logger.debug("Looking for package {} with suffix {}", name, suffix)
    val path: Path = using(Files.newDirectoryStream(appDir)) {dirs =>
        for (val path <- dirs) {
            val matcher = packagePattern.matcher(path.getFileName.toString)
            if (matcher.matches() && matcher.group(1).equals(name))
                if (suffix.isDefined) {
                    if (matcher.group(2) != null && matcher.group(2).equals(suffix.get))
                        return path
                } else
                    return path
        }
        throw new PackageNotFoundException(this, name, suffix)
    }
    logger.debug("Found package is {}", path)
    path
}
Run Code Online (Sandbox Code Playgroud)

我可以以某种方式做一个本地回报吗?谢谢.

Jam*_*Iry 10

或者你可以摆脱你的循环并将其替换为你想要做的事情:"找到"

def findPackage(name: String, suffix: Option[String] = None): Path = {
    logger.debug("Looking for package {} with suffix {}", name, suffix)

    def matching(path : Path) : Boolean = {
        val matcher = packagePattern.matcher(path.getFileName.toString)
        matcher.matches && matcher.group(1).equals(name) && (!suffix.isDefined || (matcher.group(2) != null && matcher.group(2).equals(suffix.get))
    }

    val path: Path = using(Files.newDirectoryStream(appDir)) {dirs =>
       dirs find matching getOrElse {throw new PackageNotFoundException(this, name, suffix)}
    }

    logger.debug("Found package is {}", path)
    path
}
Run Code Online (Sandbox Code Playgroud)


Vla*_*dim 8

我完全支持James Iry的建议,但为了示范:

def findPackage(name: String, suffix: Option[String] = None): Path = {
    logger.debug("Looking for package {} with suffix {}", name, suffix)
    val path: Path = using(Files.newDirectoryStream(appDir)) {dirs =>
        try {
          for (val path <- dirs) {
              val matcher = packagePattern.matcher(path.getFileName.toString)
              if (matcher.matches() && matcher.group(1).equals(name))
                  if (suffix.isDefined) {
                      if (matcher.group(2) != null && matcher.group(2).equals(suffix.get))
                          return path
                  } else
                     return path
          }
          throw new PackageNotFoundException(this, name, suffix)
        } catch { case e:scala.runtime.NonLocalReturnControl[Path] => e.value}
    }
    logger.debug("Found package is {}", path)
    path
}
Run Code Online (Sandbox Code Playgroud)

改变了什么?

try{}在匿名函数的主体周围添加了一个块,然后catch在最后查找scala.runtime.NonLocalReturnControl异常表达式,然后我提取并传递返回值.

为什么会这样?

从嵌套的匿名函数返回会引发scala.runtime.NonLocalReturnControl由主机函数或方法捕获的异常.

Scala语言规范,第6.20节返回表达式:

...从嵌套的匿名函数返回是通过抛出和捕获scala.runtime.NonLocalReturnException来实现的.返回点和封闭方法之间的任何异常捕获都可能会看到异常.密钥比较确保这些异常仅由返回终止的方法实例捕获.

如果返回表达式本身是匿名函数的一部分,则在执行返回表达式之前,f的封闭实例可能已经返回.在这种情况下,抛出的scala.runtime.NonLocalReturnException将不会被捕获,并将向上传播调用堆栈.