Во-первых, как указал @pst, ваш пример может быть полностью реализован с использованием статической типизации, он не требует динамической типизации.
Во-вторых, если вы хотите программировать на динамически типизированном языке, программируйте на динамически типизированном языке.
Как говорится, вы можете действительно делать что-то подобное в Scala. Вот упрощенный пример:
class Dict[V](args: (String, V)*) extends Dynamic {
import scala.collection.mutable.Map
private val backingStore = Map[String, V](args:_*)
def typed[T] = throw new UnsupportedOperationException()
def applyDynamic(name: String)(args: Any*) = {
val k = if (name.endsWith("_=")) name.dropRight(2) else name
if (name.endsWith("_=")) backingStore(k) = args.first.asInstanceOf[V]
backingStore.get(k)
}
override def toString() = "Dict(" + backingStore.mkString(", ") + ")"
}
object Dict {
def apply[V](args: (String, V)*) = new Dict(args:_*)
}
val t1 = Dict[Any]()
t1.bar_=("quux")
val t2 = new Dict("foo" -> "bar", "baz" -> "quux")
val t3 = Dict("foo" -> "bar", "baz" -> "quux")
t1.bar // => Some(quux)
t2.baz // => Some(quux)
t3.baz // => Some(quux)
Как видите, вы были довольно близки, на самом деле. Ваша главная ошибка заключалась в том, что Dynamic
является признаком, а не классом, поэтому вы не можете создать его экземпляр, вам нужно смешать его. И вам, очевидно, нужно на самом деле определить, что вы хотите, то есть реализовать typed
и applyDynamic
.
Если вы хотите, чтобы ваш пример работал, есть пара сложностей. В частности, вам нужно что-то вроде разнородной карты с сохранением типов в качестве резервного хранилища. Также есть некоторые синтаксические соображения. Например, foo.bar = baz
переводится только в foo.bar_=(baz)
, если существует foo.bar_=
, чего нет, потому что foo
является Dynamic
объектом.