Scala打开写入stdout或文件

时间:2013-07-10 16:41:16

标签: java scala io stdout

假设我有一个功能

writeToFileOrStdout(fname: String = Nil) = { ... }

如果用户传递了fname的字符串值,那么我想打开一个具有该名称的文件并写入该文件;否则,我想打印到stdout。我总是可以编写一个if语句来处理这个问题,但是如何在fname上编写case语句并打开正确的相应outputStream呢?

    val outStream = fname match {
      case Nil => ???
      case _   => new java.io.FileOutputStream(new java.io.File(fname))
    }
    outStream.write( ... )

谢谢!

3 个答案:

答案 0 :(得分:4)

为什么不将函数重写为:

def writeToFileOrStdout(fname: Option[String] = None) = {
  val outStream = fname match{
    case Some(name) => new java.io.FileOutputStream(new java.io.File(name))
    case None => System.out
  }
  ...
}

使用Option作为可选输入始终是一个好主意,而不是使用null。这基本上就是它的用途。在良好的scala代码中,您将看不到对null的明确引用。

实际上,你的代码甚至都没有为我编译。 Nil用于表示空列表,而不是空值或非提供的String

答案 1 :(得分:2)

增加cmbaxter的回应...

String的可能null值映射到Option[String]非常简单:Option(stringValue)将返回None stringValue为{{1} }和null,其中非null。

因此,你可以:

  1. Some(stringValue)

  2. 如果您坚持使用writeToFileOrStdout(Option(stringValue))(可能还有String值)作为null的参数,那么在内部使用writeToFileOrStdout并匹配到它返回::

    Option(fname)

答案 2 :(得分:0)

为了进一步增强cmbaxter的响应,您可以考虑写一下:

def filenameToOutputStream(name: String) = 
  new java.io.FileOutputStream(new java.io.File(name))

def writeToFileOrStdout(fname: Option[String] = None) = {
  val outStream = fname map filenameToOutputStream getOrElse System.out
  ...
}

正如帖子Idiomatic Scala: Your Options Do Not Match所暗示的那样,这可能是更惯用的Scala。