【问题标题】:Practical uses of a Dynamic type in ScalaScala 中动态类型的实际使用
【发布时间】:2011-06-10 04:47:21
【问题描述】:

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

【问题讨论】:

  • 如果没有语言支持(例如 C#.4 中的 dynamic),我并没有真正“看到”该提交发生了什么。看看它是如何适应的会很有趣。
  • 这个问题的答案已经过时了,实际答案请参见:How does type Dynamic work and how to use it?

标签: scala types


【解决方案1】:

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

[edit] Martin 进一步证实了这一点here

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

    【解决方案3】:

    我猜想动态类型可以用来实现 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")
    

    如果要添加动态元编程,则需要 Dynamic 类型以允许调用在运行时添加的方法..

    【讨论】:

    • 您的第三个示例不应该使用大写 P:Person.findByName("Bob") 吗?
    猜你喜欢
    • 2014-09-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-18
    • 2014-10-25
    • 1970-01-01
    • 2015-09-05
    相关资源
    最近更新 更多