Scala 中的动态属性
Scala 支持动态属性之类的东西吗?示例:
val dog = new Dynamic // Dynamic does not define 'name' nor 'speak'.
dog.name = "Rex" // New property.
dog.speak = { "woof" } // New method.
val cat = new Dynamic
cat.name = "Fluffy"
cat.speak = { "meow" }
val rock = new Dynamic
rock.name = "Topaz"
// rock doesn't speak.
def test(val animal: Any) = {
animal.name + " is telling " + animal.speak()
}
test(dog) // "Rex is telling woof"
test(cat) // "Fluffy is telling meow"
test(rock) // "Topaz is telling null"
我们在 Scala 中能得到的最接近的东西是什么?如果有像“addProperty”这样的东西允许像普通字段一样使用添加的属性,那就足够了。
我对结构类型声明(“类型安全鸭子类型”)不感兴趣。我真正需要的是在运行时添加新的属性和方法,以便该对象可以由期望添加的元素存在的方法/代码使用。
Does Scala support something like dynamic properties? Example:
val dog = new Dynamic // Dynamic does not define 'name' nor 'speak'.
dog.name = "Rex" // New property.
dog.speak = { "woof" } // New method.
val cat = new Dynamic
cat.name = "Fluffy"
cat.speak = { "meow" }
val rock = new Dynamic
rock.name = "Topaz"
// rock doesn't speak.
def test(val animal: Any) = {
animal.name + " is telling " + animal.speak()
}
test(dog) // "Rex is telling woof"
test(cat) // "Fluffy is telling meow"
test(rock) // "Topaz is telling null"
What is the closest thing from it we can get in Scala? If there's something like "addProperty" which allows using the added property like an ordinary field, it would be sufficient.
I'm not interested in structural type declarations ("type safe duck typing"). What I really need is to add new properties and methods at runtime, so that the object can be used by a method/code that expects the added elements to exist.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
Scala 2.9 将有一个经过特殊处理的 Dynamic 特征,这可能正是您正在寻找的。
这个博客有很多关于它的内容:http://squirrelsewer.blogspot.com/2011/ 02/scalas-upcoming-dynamic-capability.html
我猜想在invokeDynamic方法中你需要检查“name_=”、“speak_=”、“name”和“speak”,你可以将值存储在私有映射中。
Scala 2.9 will have a specially handled Dynamic trait that may be what you are looking for.
This blog has a big about it: http://squirrelsewer.blogspot.com/2011/02/scalas-upcoming-dynamic-capabilities.html
I would guess that in the invokeDynamic method you will need to check for "name_=", "speak_=", "name" and "speak", and you could store values in a private map.
我想不出真正需要在运行时动态添加/创建方法/属性的原因除非也允许动态标识符 - 和/或 - 神奇的绑定到外部动态源(JRuby 或 JSON 是两个很好的例子)。
否则,发布的示例可以通过“匿名”类型和结构类型完全使用 Scala 中现有的静态类型来实现。不管怎样,并不是说“动态”不方便(正如 0__ 指出的那样,即将到来——随意“走边缘”;-)。
考虑一下:
但是,这种方法很快就会变得很麻烦(要“添加”新属性,需要创建一种新类型并将当前数据复制到其中),并且部分利用了示例代码的简单性。也就是说,实际上不可能以这种方式创建真正的“开放”对象;对于“开放”数据,某种 Map 可能是当前 Scala (2.8) 实现中更好/可行的方法。
快乐编码。
I can not think of a reason to really need to add/create methods/properties dynamically at run-time unless dynamic identifiers are also allowed -and/or- a magical binding to an external dynamic source (JRuby or JSON are two good examples).
Otherwise the example posted can be implemented entirely using the existing static typing in Scala via "anonymous" types and structural typing. Anyway, not saying that "dynamic" wouldn't be convenient (and as 0__ pointed out, is coming -- feel free to "go edge" ;-).
Consider:
However, this method can quickly get cumbersome (to "add" a new attribute one would need to create a new type and copy over the current data into it) and is partially exploiting the simplicity of the example code. That is, it's not practically possible to create true "open" objects this way; in the case for "open" data a Map of sorts is likely a better/feasible approach in the current Scala (2.8) implementation.
Happy coding.
首先,正如 @pst 指出的,您的示例可以完全使用静态类型来实现,它不需要动态类型。
其次,如果您想使用动态类型语言进行编程,就使用动态类型语言进行编程。
话虽这么说,您实际上可以在 Scala 中做类似的事情。这是一个简单的例子:
正如您所看到的,实际上您已经非常接近了。你的主要错误是
Dynamic
是一个特征,而不是一个类,所以你不能实例化它,你必须将它混合进去。而且你显然必须实际定义你想要它做什么,即实现typed
和applyDynamic
。如果您希望您的示例能够正常工作,那么会遇到一些复杂的情况。特别是,您需要诸如类型安全的异构映射之类的东西作为后备存储。此外,还有一些语法方面的考虑。例如,如果
foo.bar_=
存在,则foo.bar = baz
仅翻译为foo.bar_=(baz)
,但事实并非如此不是,因为foo
是一个Dynamic
对象。First off, as @pst pointed out, your example can be entirely implemented using static typing, it doesn't require dynamic typing.
Secondly, if you want to program in a dynamically typed language, program in a dynamically typed language.
That being said, you can actually do something like that in Scala. Here is a simplistic example:
As you can see, you were pretty close, actually. Your main mistake was that
Dynamic
is a trait, not a class, so you can't instantiate it, you have to mix it in. And you obviously have to actually define what you want it to do, i.e. implementtyped
andapplyDynamic
.If you want your example to work, there are a couple of complications. In particular, you need something like a type-safe heterogenous map as a backing store. Also, there are some syntactic considerations. For example,
foo.bar = baz
is only translated intofoo.bar_=(baz)
iffoo.bar_=
exists, which it doesn't, becausefoo
is aDynamic
object.