2011-01-17 9 views
41

Neben der Integration mit dynamischen Sprachen auf der JVM, was sind die anderen mächtigen Verwendungen einer Dynamic type in einer statisch typisierten Sprache wie Scala?Praktische Anwendungen eines dynamischen Typs in Scala

+1

Ohne Sprachunterstützung (z. B. "dynamisch" in C# .4), ich "sehe" nicht wirklich, was mit diesem Commit vor sich geht. Wäre interessant zu sehen, wie es passt. –

+1

Die Antworten auf diese Frage sind extrem veraltet, für tatsächliche Antworten siehe: [Wie funktioniert Typ Dynamic und wie funktioniert es?] (Http://stackoverflow.com/q/15799811/465304) – sschaef

Antwort

21

Ich denke, ein dynamischer Typ könnte verwendet werden, um einige der Funktionen in JRuby, Groovy oder anderen dynamischen JVM-Sprachen wie dynamisches Metaprogrammieren und method_missing zu implementieren.

Zum Beispiel Erstellen einer dynamischen Abfrage ähnlich Active Record in Rails, wo ein Methodenname mit Parametern in eine SQL-Abfrage im Hintergrund übersetzt wird. Dies verwendet die method_missing-Funktionalität in Ruby. So etwas wie diese (in der Theorie - habe nicht versucht, etwas Derartiges zu implementieren):

class Person(val id: Int) extends Dynamic { 
    def _select_(name: String) = { 
    val sql = "select " + name + " from Person where id = " id; 
    // run sql and return result 
    } 

    def _invoke_(name: String)(args: Any*) = { 
    val Pattern = "(findBy[a-zA-Z])".r 
    val sql = name match { 
     case Pattern(col) => "select * from Person where " + col + "='" args(0) + "'" 
     case ... 
    } 
    // run sql and return result 
    } 
} 

erlauben Nutzung wie dieser, wo Sie ‚Name‘ Methoden aufrufen können und ‚findByName‘, ohne sie explizit in der Klasse Person definiert ist, :

val person = new Person(1) 

// select name from Person where id = 1 
val name = person.name 

// select * from Person where name = 'Bob' 
val person2 = person.findByName("Bob") 

Wenn dynamisches metaprogramming hinzugefügt wurde, würde der dynamische Typ Methoden zu ermöglichen, benötigt Aufruf, die während der Laufzeit hinzugefügt wurden ..

+0

Sollten Sie das dritte Beispiel nicht verwenden, verwenden Sie das P: 'Person.findByName (" Bob ")'? – anishpatel

2

Man könnte es auch für syntaktischen Zucker auf Karten verwenden:

class DynamicMap[K, V] extends Dynamic { 
    val self = scala.collection.mutable.Map[K, V]() 
    def _select_(key: String) = self.apply(key) 
    def _invoke_(key: String)(value: Any*) = 
    if (value.nonEmpty) self.update(key, value(0).asInstanceOf[V]) 
    else throw new IllegalArgumentException 
} 

val map = new DynamicMap[String, String]() 

map.foo("bar") // adds key "foo" with value "bar"  
map.foo   // returns "bar" 

Um ehrlich zu sein, dies erspart Ihnen nur ein paar Tastenanschläge aus:

val map = new Map[String, String]() 
map("foo") = "bar" 
map("foo") 
+1

Beachten Sie, dass dieses Beispiel aus mehreren Gründen nicht ganz funktioniert, aber ich denke nicht, dass es viel Sinn macht, dies weiter zu erforschen, bevor das Feature stabiler ist. –

+0

Ich habe es hier funktioniert: [http://stackoverflow.com/questions/14876856/simple-scala-macro] –

Verwandte Themen