[原创] scala 动态方法

coollzh 2011-09-29
今天看了scala days 2011上的一个牛人的ppt:SCALA vs RUBY
该ppt中列举了scala和ruby的特性对比,其中提到dynamic这块,说最新版的scala 2.9支持动态方法,代码是这样的:

class Animal extends Dynamic {
	def _select_( name : String ) = println( "Animal says " + name )
	def _invoke_( name : String, args : Any* ) = {
		println( "Animal wants to " + name + args.mkString( ", " ) )
		this
	}
}

	val animal = new Animal()
	animal.qualk // => Animal says qualk
	animal.say( "hello" ) // => Animal wants to say hello


不知道为什么在scala命令下编译不过,报animal没有对象member,我用的是scala 2.9.1 final,应该没有问题的啊
coollzh 2011-09-30

经和原作者邮件沟通,说这个动态的新特性,是2.9的版本才支持的,需要JVM7.0, 悲催
kidneyball 2011-10-03
从来不觉得这种动态性有什么好处,又慢,又破坏了程序的可读性,又没有编译期检查,又无法利用IDE的自动补全功能。而且就算语言层面不支持,用隐式转换和结构类型就能解决大部分问题了。就算一定要用这种按名称访问的方式,用一个传入字符串方法名和对象List参数的代理方法,再结合结构类型就能实现了。换一种表现方式,除了好看一点,让读程序的人觉得很奇妙之外,没什么实质性的好处。
liusong1111 2011-10-11
kidneyball 写道
从来不觉得这种动态性有什么好处,又慢,又破坏了程序的可读性,又没有编译期检查,又无法利用IDE的自动补全功能。而且就算语言层面不支持,用隐式转换和结构类型就能解决大部分问题了。就算一定要用这种按名称访问的方式,用一个传入字符串方法名和对象List参数的代理方法,再结合结构类型就能实现了。换一种表现方式,除了好看一点,让读程序的人觉得很奇妙之外,没什么实质性的好处。


强烈同意。

Dynamic的实现很像Map的get/set:
对于map(key), map(key)=value 在编译时映射到 apply, update方法上。

目前Dynamic的做法相当于在编译时做了隐式转换了。

我也倾向于kidneyball的想法,对动态的方法或属性进行显式声明(需要修改scala的语法),比如这样:

dynamic.'meth(args...)

这样看起来更直观。话又说回来,这是个取舍问题。再说,scala的方法名不象java限制各种特殊字符的出现(甚至还支持用``括起那些诡异的名字),这样本来对于DSL的支持是有利的,却不容易再对语法进行扩展了。

以我以往ruby(rails)的开发经验,需要用到dynamic产生动态属性的地方,十分的少。唯一有必要的,使用ActiveRecord映射的model,根据数据库产生字段名。但对于ruby的另一个orm库DataMapper来说,又是显式写上去的,而且还会产生明显的附加好处。所以,真看不出动态属性的必要性。

至于动态方法,java的各种字节码增强技术确实帮助有限,一旦开启Dynamic功能,就开放了开发者的想像力,将会打开一个永远关不上的闸门,比较危险。这样相当于放弃了在编译器和语法上进一步雕琢的信心。

话说,scala的reflection也得加紧与时俱进了。

纠结。
Global site tag (gtag.js) - Google Analytics