2

假设我有一个功能

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

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

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

谢谢!

4

3 回答 3

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用于表示一个空列表,而不是 null 或未提供的String

于 2013-07-10T17:28:23.840 回答
2

为了增强 cmbaxter 的响应...

String将 a与可能的null值映射到Option[String]是微不足道的:Option(stringValue)将返回Nonewhere stringValueisnullSome(stringValue)where 非 null。

因此,您可以:

  1. writeToFileOrStdout(Option(stringValue)), 或者

  2. 如果您坚持String(并且可能是一个null值)作为 的参数writeToFileOrStdout,则在内部使用Option(fname)并匹配它返回的内容::

    def writeToFileOrStdout(fname: String = null) = {
      val outStream = Option(fname) match{
        case Some(name) => new java.io.FileOutputStream(new java.io.File(name))
        case None => System.out
      }
      ...
    }
    
于 2013-07-10T18:43:53.133 回答
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 Sc​​ala: Your Options Do Not Match后所说,这可能是更惯用的 Scala。

于 2015-10-01T20:54:17.103 回答