2011-10-08 8 views
22

Obecnie robię moje pierwsze kroki w Scali, więc szukam najlepszych praktyk w zbliżaniu się do wspólnych problemów. Poniżej znajduje się kod, który nie działa, ale opisuje to, co chcę zrobić. Czy mógłbyś polecić najlepsze podejście do tego problemu?Scala ciąg wzorców pasujących do najlepszych praktyk

def resolveDriver(url: String) = { 
    url match { 
     case url.startsWith("jdbc:mysql:") => "com.mysql.jdbc.Driver" 
     case url.startsWith("jdbc:postgresql:") => "org.postgresql.Driver" 
     case url.startsWith("jdbc:h2:") => "org.h2.Driver" 
     case url.startsWith("jdbc:hsqldb:") => "org.hsqldb.jdbcDriver" 
     case _ => throw new IllegalArgumentException 
    } 
    } 
+2

Zobacz też [to pytanie] (http://stackoverflow.com/q/7586605/53013) na inny sposób, aby rozwiązać ten problem, jeśli dopasowaną częścią jest cały protokół. –

Odpowiedz

39

Pod względem składni, można modyfikować tylko odrobinę ci przypadków stwierdzenia:

case url if url.startsWith("jdbc:mysql:") => "com.mysql.jdbc.Driver" 

To po prostu wiąże wartość url do wyrażenia wzoru (który jest również url) i dodaje strażnika wyrażenie za pomocą testu. To powinno spowodować, że kod się skompiluje.

Aby uczynić go trochę bardziej scala-jak można wrócić opcję [String] (usunąłem klauzulę para, ponieważ jest to tylko dla ilustracji):

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 
} 

To chyba chcesz zarządzać wyjątki.

+0

Dzięki! Właśnie tego szukałem! Cieszę się, że zadałem to pytanie, ponieważ przygotowywałam się już do stworzenia klasy przypadku, która pachniała jak nadmierna komplikacja. Dziękuję również za poprawienie mnie w rzucie wyjątkowym. –

10

Oto alternatywny sposób. Zapisz wszystkie mapowania na mapie, a następnie użyj metody collectFirst, aby znaleźć dopasowanie. Rodzaj podpis collectFirst jest:

def TraversableOnce[A].collectFirst[B](pf: PartialFunction[A, B]): Option[B] 

Zastosowanie:

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) 
+0

Dzięki, ale czy nie jest to, co proponujecie abstrakcję na "mecz"? –

+0

@mojojojo: Niezupełnie. Zbiór wyrażeń 'case' następujących po' dopasowaniu' stanowi "PartialFunction". 'collectFirst' to metoda, która akceptuje' PartialFunction', pętle nad kolekcją i zwraca pierwsze dopasowanie znalezione jako opakowane w 'Some'. (zwraca 'None', jeśli nie znaleziono pasującego elementu). – missingfaktor

+0

@mojojojo: Zobacz źródło: http://goo.gl/Q4UNz – missingfaktor

Powiązane problemy