String pattern matching best practice
Here is an alternate way. Store all the mappings in a map and then use collectFirst
method to find the match. Type signature of collectFirst
is:
def TraversableOnce[A].collectFirst[B](pf: PartialFunction[A, B]): Option[B]
Usage:
scala> val urlMappings = Map("jdbc:mysql:" -> "com.mysql.jdbc.Driver", "jdbc:postgresql:" -> "org.postgresql.Driver")
urlMappings: scala.collection.immutable.Map[java.lang.String,java.lang.String] = Map(jdbc:mysql: -> com.mysql.jdbc.Drive
r, jdbc:postgresql: -> org.postgresql.Driver)
scala> val url = "jdbc:mysql:somestuff"
url: java.lang.String = jdbc:mysql:somestuff
scala> urlMappings collectFirst { case(k, v) if url startsWith k => v }
res1: Option[java.lang.String] = Some(com.mysql.jdbc.Driver)
In terms of syntax, you can modify just a tiny bit you case statements:
case url if url.startsWith("jdbc:mysql:") => "com.mysql.jdbc.Driver"
This simply binds the value url
to the pattern expression (which is also url
) and adds a guard expression with a test. That should make the code compile.
To make it a little bit more scala-like, you can return an Option[String] (I removed a couple clause since it's just for illustration):
def resolveDriver(url: String) = url match {
case u if u.startsWith("jdbc:mysql:") => Some("com.mysql.jdbc.Driver")
case u if u.startsWith("jdbc:postgresql:") => Some("org.postgresql.Driver")
case _ => None
}
That is unless you want to manage exceptions.