温故知新: Groovy Recipes (上)
Groovy Recipes 是 2008 的老书了(没办法,貌似 Groovy 的基础读物之后就没有新的了),胜在够薄,拿来复习下 Groovy 的知识吧。 2.4 Running the Groovy ShellGotcha: Why Does the Groovy Shell Forget Your Variables? //好吧,我承认3年前为这个问题纠结过
2.5 Running the Groovy ConsolegroovyConsole 不仅仅是 groovysh 的 GUI 替代品,在 Script 菜单下的 Inspect * 功能可以提供及其方便的对象浏览功能。 理论上,groovyConsole 没什么大用,但在但遇上某个不熟悉的语法特性或是类,拿 gC 来迅速实验一下会非常方便。就这一点而言,脚本化的语言胜过其前辈不是一星半点,想想当年学 Java 的时候,你是怎么玩的?(在 IDE 中)保存 -> (编译)运行 -> 撞墙 -> 修改…… 2.6 Running Groovy on a Web Server通常我们会在 Grials 下使用 groovy,但是依然可以用简单的步骤来把 groovy 整合到你的现有系统中:
3.2 Optional SemicolonsOK,下面这段话不属于技术范畴,但是写的很有趣……而且很明显他是和我一伙的:
3.4 Optional Return Statements关于为什么要少用括号、分号和 return,以及为什么要写尽可能短的代码:
3.15 Map ShortcutsGotcha: Why Does .class Work on Everything Except Maps?
注:书中没有提到 map 的减法,但是参考以下代码: 1: def m1 = [a: 1,b: 2,c: 3]
2: def m2 = [a: 2,d: 4]
3: assert m1 + m2 == [a: 2,c: 3,d: 4] 4: assert m1 - m2 == [c: 3,a: 1] 3.17 Closures and Blocks在学习 Scala 的时候,Currying 是非常重要的部分。在 Groovy 中也有同样的功能,但是以前我并未注意到这一点(虽然有用到)。 1: def calculateTax = { taxRate,amount ->
2: amount + (taxRate * amount)
3: }
4: def tax = calculateTax.curry(0.1)
5: [10,20,30].each {
6: println "Total cost: ${tax(it)}" 7: }
相比之下,Scala 的 Currying 形式上要简洁得多(毕竟人家是函数风格出身),但 Groovy 的 Currying 要好理解得多(以至于我根本没有意识到其存在)。 4.2 Autogenerated Getters and Setters由于 @ 前缀的存在,调用者可以忽视任何 access modifier 来存取任何 POGO 变量,因此通过覆写 getter/setter 来保护私有字段并不是完全有效。另外,覆写 setter 方法时并不要求参数的型别一致,只需要参数数量一样就可以(当然,参数数量必须为 1)。 4.6 Optional Parameters/Default Values这是一个很方便的特性,但我还未决定是否要在我的项目中使用这个特性。考虑如下代码,当写下一个带有默认值的方法时,Groovy 编译器实际上会自动生成多个方法以便于用户调用。 1: class OptionalParas {
2: def p(a = 'yes',b,c,d = 'no') { 3: println "$a,$b,$c,$d" 4: }
5: }
6:?
7: OptionalParas.methods.each { if(it.name == 'p') println it.parameterTypes } 8: ===>
9: [class java.lang.Object,class java.lang.Object,class java.lang.Object] 10: [class java.lang.Object,class java.lang.Object] 11: [class java.lang.Object,class java.lang.Object] 看起来没有任何问题对吗?不过我的直觉告诉我,在一个 5 行的类中运作完美的语法糖在 50 行的代码下未必行得通。在上面那个类中,当你想要重载方法 p 时,必须小心考虑参数的类型和个数,否则就会和原来的 p 方法产生冲突。 4.8 Calling Groovy from JavaGotcha: Groovy Ignores the Private Modifier //看起来 private 修饰符对 Groovy 来说是直接无视了,怎么看待这个问题?
5.5 Using Shell Wildcards in Groovy Scripts 1: //in Windows:
2: println "cmd /c dir *.groovy".execute().text 3: def c = ["cmd","/c","dir *.groovy" ].execute().text 4: println c
5: //in Unix / Linux / Mac OS X: 6: def output = ["sh","-c","ls -al *.groovy" ].execute().text 7: println output
8: //sadly,these don't work 9: println "ls -al *.groovy".execute().text 10: println "sh -c ls -al *.groovy".execute().text 5.7 Waiting for a Shell Command to Finish Before Continuing 1: def p = "convert -crop 256x256 full.jpg tile.jpg".execute()
2: p.waitFor()
3: println "ls".execute().text 5.11 Calling Another Groovy ScriptCalling Methods in Another Script 1: //hello3.groovy
2: if(args){ 3: println "Hello ${args[0]}" 4: if(args.size() > 1){ 5: println "...and your little dog,too: ${args[1]}" 6: }
7: }
8: def sayHola(){
9: println "Hola" 10: }
11: //goodbye3.groovy 12: hello3.main()
13: hello3.main("Glenda" ) 14: hello3.main("Dorothy","Toto" ) 15: println "Goodbye" 16: h = new hello3() 17: h.sayHola()
Calling Another Script in a Different Directory 1: evaluate(new File("/some/other/dir/hello.groovy" ))
6.1 Listing All Files in a Directory 1: new File('.').eachFileMatch(~/.*/.jsp/){ println it }
File.eachFileMatch technically accepts any class with a method boolean isCase(String s). This means you could expand the example to include a JspFilter class: 1: class JspFilter {
2: boolean isCase(String filename) { filename.endsWith('.jsp') } 4:?
5: new File('.').eachFileMatch(new JspFilter()){ println it } 6.4 Copying FilesCopying Binary Files 1: def src = new File('src.jpg')
2: new File('dest.jpg').withOutputStream { it.write src.readBytes() } 6.5 Using AntBuilder to Copy a File 1: def ant = new AntBuilder()
2: ant.copy(file: 'src.txt',tofile: 'dest.txt') Copying a File to a Directory / Overwriting the Destination File 1: ant.copy(file: 'src.txt',todir: '../backup')
'dest.txt',overwrite: true) 6.9 Creating a ZIP File/Tarball 2: ant.zip(basedir: "images",destfile: "../backup.zip")
3: ant.tar(basedir: "images",destfile: "../backup.tar") 4: ant.gzip(zipfile: "../backup.tar.gz",src: "../backup.tar") 5: ant.bzip2(zipfile: "../backup.tar.bz2",src: "../backup.tar") 7: ant.zip(destfile: "../backup.zip") { 8: fileset(dir: "images") { 9: include(name: "**/*.jpg") 10: exclude(name: "**/*.txt") 11: }
12: }
6.10 Unzipping/Untarring Files 1: ant.unzip(src: "../backup.zip",dest: "/dest")
2: ant.gunzip(src: "../backup.tar.gz") 3: ant.bunzip2(src: "../backup.tar.bz2") 4: ant.untar(src: "../backup.tar",dest: "/dest") 5:?
6: ant.unzip(src: "../backup.zip",dest: "/dest") { 7: patternset {
8: include(name: "**/*.jpg") 9: //exclude(name: "**/*.txt") 10: }
11: }
? ? ? #END (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |