Scala 中动态类型的实际使用

发布于 2024-10-12 22:37:47 字数 152 浏览 1 评论 0原文

除了与 JVM 上的动态语言集成之外,动态类型还有哪些其他强大用途 使用像 Scala 这样的静态类型语言?

Besides integration with dynamic languages on the JVM, what are the other powerful uses of a Dynamic type in a statically typed language like Scala?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

橘寄 2024-10-19 22:37:47

我猜想动态类型可以用来实现 JRuby、Groovy 或其他动态 JVM 语言中的一些功能,例如动态元编程和 method_missing。

例如,创建类似于 Rails 中的 Active Record 的动态查询,其中带参数的方法名称在后台转换为 SQL 查询。这是使用 Ruby 中的 method_missing 功能。像这样的东西(理论上 - 没有尝试实现类似的东西):

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

如果动态元编程是添加后,需要动态类型来允许调用在运行时添加的方法。

I guess a dynamic type could be used to implement several of the features found in JRuby, Groovy or other dynamic JVM languages, like dynamic metaprogramming and method_missing.

For example creating a dynamic query similar to Active Record in Rails, where a method name with parameters is translated to an SQL query in the background. This is using the method_missing functionality in Ruby. Something like this (in theory - have not tried to implement anything like this):

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

Allowing usage like this, where you can call methods 'name' and 'findByName' without having them explicitly defined in the Person class:

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

If dynamic metaprogramming was to be added, the Dynamic type would be needed to allow invoking methods that have been added during runtime..

你穿错了嫁妆 2024-10-19 22:37:47

Odersky 表示,主要动机是与动态语言集成:http://groups.google。 com/group/scala-language/msg/884e7f9a5351c549

[编辑] Martin 进一步证实了这一点 此处

Odersky says the primary motivation was integration with dynamic languages: http://groups.google.com/group/scala-language/msg/884e7f9a5351c549

[edit] Martin further confirms this here

哭泣的笑容 2024-10-19 22:37:47

您还可以将它用作地图上的语法糖:

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

You might also use it for syntactic sugar on maps:

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"

To be honest this only saves you a couple of keystrokes from:

val map = new Map[String, String]()
map("foo") = "bar"
map("foo")
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文