以更实用的方式更改if-else-construct?

Twi*_*ton 6 functional-programming if-statement scala pattern-matching

是否有可能在更实用的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"
}
Run Code Online (Sandbox Code Playgroud)

我试图使用模式匹配,但它不起作用.所以我很好奇一个好的解决方案.

提前致谢!

猩猩

ten*_*shi 35

MIME类型映射

我同意@glowcoder.我发现至少在这种特殊情况下,最好使用MIME类型映射.这是一个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"
Run Code Online (Sandbox Code Playgroud)

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

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

然后像这样使用它: 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"
}
Run Code Online (Sandbox Code Playgroud)

此解决方案的优势在于您可以在以下条件下获得更复杂的逻辑:

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

与自定义提取器匹配的模式

还有另一种使用模式匹配的方法.您可以为文件扩展名编写自己的提取器,然后在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"
}
Run Code Online (Sandbox Code Playgroud)

  • 请注意,您可以将`.DefaultValue("application/octet-stream")`附加到`MimeTypesMapping`,然后在`getMIMETypes`中使用`MimeTypesMapping(x)`而不是选项. (3认同)

cor*_*iKa 5

我不确切知道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");
Run Code Online (Sandbox Code Playgroud)

然后在你的功能中使用

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

更新:看起来Scala使用的地图非常相似:

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