将if-else结构更改为更实用的风格



是否有可能在Scala的函数式风格中改变这种if-else-construct ?

def getMIMEType(document: String): String = {
  if (document.endsWith(".pdf")) {
    return "application/pdf"
  } else if (document.endsWith(".dxf")) {
    return "application/dxf"
  } else if (document.endsWith(".jpg")) {
    return "image/jpeg"
  } else return "application/octet-stream"
}

我尝试使用模式匹配,但它不起作用。所以我很想找到一个好的解决方案。

MIME-Type映射

我同意@glowcoder。我发现,至少在这种特殊情况下,最好使用MIME-Types映射。下面是Scala版本:

val MimeTypesMapping = Map(
  ".pdf" -> "application/pdf",
  ".dxf" -> "application/dxf",
  ".jpg" -> "image/jpeg"
)
def extension(fileName: String) = fileName substring (fileName lastIndexOf ".")
def getMIMEType(document: String) =
  MimeTypesMapping get extension(document) getOrElse "application/octet-stream"

同样,正如Rex Kerr所指出的,您可以直接将默认值添加到映射定义中:

val MimeTypesMapping = Map(
  ".pdf" -> "application/pdf",
  ".dxf" -> "application/dxf",
  ".jpg" -> "image/jpeg"
) withDefaultValue "application/octet-stream" 

,然后这样使用:MimeTypesMapping(extension(document))

模式匹配

如果你不喜欢第一个解决方案,那么你可以使用模式匹配代替:

def getMIMEType(document: String) = extension(document) match {
  case ".pdf" => "application/pdf"
  case ".dxf" => "application/dxf"
  case ".jpg" => "image/jpeg"
  case _      => "application/octet-stream"
}

这个解决方案的优点是,您可以在如下条件下执行更复杂的逻辑:

def getMIMEType(document: String) = extension(document) match {
  // ...
  case ".jpg" | ".jpeg" => "image/jpeg"
  // ...
}

使用自定义提取器进行模式匹配

还有另一种使用模式匹配的方法。您可以为文件扩展名编写自己的提取器,然后在match中使用它:

object Extension {
  def unapply(fileName: String): Option[String] = {
    val idx = fileName lastIndexOf "."
    if (idx != -1) Some(fileName substring idx) else None
  }
}
def getMIMEType(document: String) = document match {
  case Extension(".pdf") => "application/pdf"
  case Extension(".dxf") => "application/dxf"
  case Extension(".jpg") => "image/jpeg"
  case _                 => "application/octet-stream"
}

我不知道scala的内置结构是什么,但听起来你想要一个映射。例如,Java使用

val map = scala.collection.mutable.HashMap[String, String]()
map.put(".pdf","application/pdf");
map.put(".dxf","application/dxf");
map.put(".jpg","image/jpeg");

然后在函数中使用

def ext = getExtension(document); // assume this exists, eh?
if(map.containsKey(ext)) return map.get(ext);
return "application/octet-stream";

更新:看起来Scala使用了一个非常相似的map:

http://www.scala-lang.org/api/rc/scala/collection/mutable/Map.html

随着我上面的评论,我想优化它,使它在实际的scala

    def getMIMEType(document: String): String = {
        if (document endsWith ".pdf") {
             return "application/pdf"
        } 
        if (document endsWith ".dxf") {
             return "application/dxf"
        } 
        if (document endsWith ".jpg") {
             return "image/jpeg"
        } 
             "application/octet-stream"
    }

我在这里看到代码不能同时满足两个条件中的任何一个。所以我建议使用上面的代码。此外,如果对于最后一个返回语句,即"application/octet-stream",你可以使用适当的"if条件",如果你找出最后一行的"if",那么所有的返回都可以被删除,否则上面的代码是好的。

也不需要提及返回类型。

    def getMIMEType(document: String): String = {} 

可以写成:

    def getMIMEType(document: String) = {} 

最新更新