简体   繁体   中英

Scala opening write to stdout or file

Let's say I have a function

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

If the user passes a string value for fname, then I'd like to open a file with that name and write to it; otherwise, I'd like to print to stdout. I could always just write an if statement to take care of this, but how would I write a case statement on fname and open the correct corresponding outputStream?

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

Thanks!

Why not rewrite the function as:

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
  }
  ...
}

It's always a good idea to use Option for an optional input as opposed to using null . That's basically what it's there for. In good scala code, you will not see explicit references to null .

In fact, your code doesn't even compile for me. Nil is used to represent an empty list, not a null or non supplied String .

To augment cmbaxter's response...

Mapping a String with a possible null value to Option[String] is trivial: Option(stringValue) will return None where stringValue is null , and Some(stringValue) where non-null.

Thus, you can either:

  1. writeToFileOrStdout(Option(stringValue)) , or

  2. If you're stuck on String (and possibly a null value) as the parameter to writeToFileOrStdout , then internally use Option(fname) and match to what it returns::

     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 } ... } 

To further augment cmbaxter's response, you might consider writing this:

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
  ...
}

As the post Idiomatic Scala: Your Options Do Not Match suggests, this might be more idiomatic Scala.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM