在 Scala 中实现 ExpandoObject
我正在尝试实现 C# 的 ExpandoObject
-就像 Scala 中的类一样。这就是它应该如何工作:
val e = new ExpandoObject
e.name := "Rahul" // This inserts a new field `name` in the object.
println(e.name) // Accessing its value.
这是我到目前为止所尝试过的:
implicit def enrichAny[A](underlying: A) = new EnrichedAny(underlying)
class EnrichedAny[A](underlying: A) {
// ...
def dyn = new Dyn(underlying.asInstanceOf[AnyRef])
}
class Dyn(x: AnyRef) extends Dynamic {
def applyDynamic(message: String)(args: Any*) = {
new Dyn(x.getClass.getMethod(message,
args.map(_.asInstanceOf[AnyRef].getClass) : _*).
invoke(x, args.map(_.asInstanceOf[AnyRef]) : _*))
}
def typed[A] = x.asInstanceOf[A]
override def toString = "Dynamic(" + x + ")"
}
class ExpandoObject extends Dynamic {
private val fields = mutable.Map.empty[String, Dyn]
def applyDynamic(message: String)(args: Any*): Dynamic = {
fields get message match {
case Some(v) => v
case None => new Assigner(fields, message).dyn
}
}
}
class Assigner(fields: mutable.Map[String, Dyn], message: String) {
def :=(value: Any): Unit = {
fields += (message -> value.dyn)
}
}
当我尝试编译此代码时,我收到一个 StackOverflowError
。请帮助我完成这项工作。 :) 谢谢。
I am trying to implement C#'s ExpandoObject
-like class in Scala. This is how it is supposed to work:
val e = new ExpandoObject
e.name := "Rahul" // This inserts a new field `name` in the object.
println(e.name) // Accessing its value.
Here is what I have tried so far:
implicit def enrichAny[A](underlying: A) = new EnrichedAny(underlying)
class EnrichedAny[A](underlying: A) {
// ...
def dyn = new Dyn(underlying.asInstanceOf[AnyRef])
}
class Dyn(x: AnyRef) extends Dynamic {
def applyDynamic(message: String)(args: Any*) = {
new Dyn(x.getClass.getMethod(message,
args.map(_.asInstanceOf[AnyRef].getClass) : _*).
invoke(x, args.map(_.asInstanceOf[AnyRef]) : _*))
}
def typed[A] = x.asInstanceOf[A]
override def toString = "Dynamic(" + x + ")"
}
class ExpandoObject extends Dynamic {
private val fields = mutable.Map.empty[String, Dyn]
def applyDynamic(message: String)(args: Any*): Dynamic = {
fields get message match {
case Some(v) => v
case None => new Assigner(fields, message).dyn
}
}
}
class Assigner(fields: mutable.Map[String, Dyn], message: String) {
def :=(value: Any): Unit = {
fields += (message -> value.dyn)
}
}
When I try to compile this code, I get a StackOverflowError
. Please help me get this work. :) Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
经过一番尝试后,它可以工作了。不过,该解决方案不是类型安全的(在这种情况下并不重要,因为这个小实用程序的目的是解决类型系统问题。:-)
Got it working after some playing around. The solution isn't typesafe though (which in this case does not matter, since the point of this little utility is to work around type system. :-)