假设我有一个功能
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( ... )
谢谢!
答案 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。
因此,你可以:
Some(stringValue)
或
如果您坚持使用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。