Практическое использование динамического типа в Scala - PullRequest
40 голосов
/ 17 января 2011

Помимо интеграции с динамическими языками в JVM, каковы другие мощные применения Динамического типа в статически типизированном языке, таком как Scala?

Ответы [ 3 ]

22 голосов
/ 17 января 2011

Я полагаю, что динамический тип мог бы использоваться для реализации некоторых функций, обнаруженных в JRuby, Groovy или других динамических языках JVM, таких как динамическое метапрограммирование и method_missing.

Например, создание динамического запроса, подобного Active Record в Rails, где имя метода с параметрами транслируется в SQL-запрос в фоновом режиме. Это использует функцию method_missing в Ruby. Как-то так (по идее - не пытались реализовать что-то подобное):

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
  }
}

Разрешение на использование, подобное этому, при котором вы можете вызывать методы 'name' и 'findByName' без их явного определения в классе Person:

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")

Если необходимо добавить динамическое метапрограммирование, тип Dynamic необходим для разрешения вызова методов, которые были добавлены во время выполнения.

4 голосов
/ 28 января 2011

Одерский говорит, что основной мотивацией была интеграция с динамическими языками: http://groups.google.com/group/scala-language/msg/884e7f9a5351c549

[править] Мартин подтверждает это здесь

2 голосов
/ 17 января 2011

Вы также можете использовать его для синтаксического сахара на картах:

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"

Если честно, это спасет вас только от пары нажатий клавиш:

val map = new Map[String, String]()
map("foo") = "bar"
map("foo")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...