2011-10-08 34 views
22

Şu anda Scala'da ilk adımları atıyorum, bu yüzden ortak sorunlara yaklaşımda en iyi uygulamaları arıyorum. Aşağıda, çalışmayan kod var, ancak ne yapmak istediğimi açıklıyor. Bu probleme en iyi yaklaşımı önerebilir misiniz? sözdizimi açısındanEn iyi uygulama ile eşleşen Scala dize deseni

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

Ayrıca bkz [Bu soru] (http://stackoverflow.com/q/7586605/53013) başka bir yolu bu sorunu çözmek için, Eşleşen bölüm tüm protokole sahipse. –

cevap

39

, sadece birazcık size vaka ifadeleri değiştirebilirsiniz:

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

Bu sadece (ayrıca url olan) desen ifadesinin değeri url bağlayan ve bir bekçi ekler bir test ile ifade. Bu kodun derlenmesini sağlamalı. Yönetmek istediğiniz sürece olan

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 
} 

:

Bir Seçenek [dize] dönebilir, bu biraz daha Scala-benzeri yapmak için (bu sadece açıklama amacıyla beri ben birkaç maddesini kaldırıldı) istisnalar.

+0

Teşekkürler! Tam olarak aradığım şey bu! Soruyu sorduğuma sevindim, çünkü zaten kendimi bir aşırı sınıflandırma gibi kokan bir sınıf oluşturmak için hazırlamıştım. Ayrıca, İstisna fırlatma konusunda beni düzeltdiğiniz için teşekkür ederim. –

10

İşte alternatif bir yol. Tüm eşlemeleri bir harita içinde saklayın ve eşleşmeyi bulmak için collectFirst yöntemini kullanın. collectFirst tipi imzadır:

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

Kullanımı:

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

Teşekkürler ama 'eşleme' üzerinde bir soyutlama önermiyor musunuz? –

+0

@mojojojo: Tam olarak değil. 'Eşleşmeyi' izleyen 'vaka' ifadeleri kümesi bir 'Kısmi İşlevi' oluşturur. "collectFirst", bir "PartialFunction" işlevini kabul eden, koleksiyon üzerinde döngü oluşturan ve "Some" seçeneğinde bulunan ilk eşleşmeyi döndüren bir yöntemdir. (eşleşme bulunamazsa, 'Yok' değerini döndürür.) – missingfaktor

+0

@mojojojo: Kaynağa bakın: http://goo.gl/Q4UNz – missingfaktor