6

对于我的第一个 Scala 程序,我正在尝试编写一个小型实用程序,它将 XML 文件从一个模式转换为另一个模式。

我开始编写一个方法,它将为我提供文件内容:

  def loadFile(filename: String, encoding: String = "utf-8"):Option[String] = {
    try
    {
      val source = scala.io.Source.fromFile(filename, encoding)
      val contents = source.mkString
      source.close()
      return Some(contents)
    }
    catch 
    {
      return None
    }

  }

但它不编译。我从该行返回“value apply is not a member of Nothing”和“value isDefinedAt is not a member of Nothing”作为错误消息return None

我可以找到返回选项的所有示例都使用匹配,但这在这里没有意义。如果由于某种原因我无法读取文件,我只想不失败。

在这种情况下我该怎么办?在 Scala 中是否有做这种事情的模式?

4

3 回答 3

7

在这种特定情况下(异常处理),我建议使用Try代替。

def loadFile(filename: String, encoding: String = "utf-8"):Option[String] = {
    Try {
      val source = scala.io.Source.fromFile(filename, encoding)
      val contents = source.mkString
      source.close()
      return Some(contents)
    }.toOption
}

但是,我建议完全不要捕获异常。您通过返回来吞下错误的原因None:是FileNotFoundException吗?一个标准IOException?是否有错误消息(Unsupported encoding想到……)?

我的经验法则是让调用者处理异常。如果他不关心错误本身,处理事情就像:

Try {loadFile("test.txt")}.toOption

更好的是,由于Try具有所有必需的方法,它可以以一种相当简洁的方式用于理解:

for(s <- Try {loadFile("test.txt")};
    i <- Try {s.toInt}) yield i

这将导致 aSuccess[Int]或 aFailure包含一个异常,准确描述出了什么问题。

于 2013-10-30T18:43:19.063 回答
5

有所有关于"catch"

在 scala 中,它应该是这样才能编译的:

  def loadFile(filename: String, encoding: String = "utf-8"):Option[String] = {
    try {
      val source = scala.io.Source.fromFile(filename, encoding)
      val contents = source.mkString
      source.close()
      Some(contents)
    } catch {
      case x: IOException =>  None
      case x => errorHandler(x) // if any other exception
    }
  }

  def errorHandler(e: Any) = None // put some logic here..

所以使用:

catch { case: x:ExceptionType ={ .. handling .. }}

在 Scalacatch中是一个函数,它接受另一个函数作为参数。因此,拥有您所拥有的东西会抱怨应用功能。case提供catch想要的功能(PartialFunction)。(简而言之)

注意:所有异常都uncheckedScalaeven中IOException

于 2013-10-30T18:12:57.067 回答
0

尝试这个:

 def loadFile(filename: String, encoding: String = "utf-8"):Option[String] = {
try
{
  val source = scala.io.Source.fromFile(filename, encoding)
  val contents = source.mkString
  source.close()
  return Some(contents)
}
catch
  {
    case e:Exception=>{
      return None
    }

  }

}

于 2013-10-30T18:13:33.973 回答