`
lixw
  • 浏览: 200915 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

Groovy "with"

阅读更多

首先看一段Java代码:

// PrintIndependenceDay.java

import java.util.Calendar;
import java.util.Date;

public class PrintIndependenceDay {

  public static void main(String[] args) {
    Calendar calendar = Calendar.getInstance();
    calendar.clear();
    calendar.set(Calendar.MONTH, Calendar.JULY);
    calendar.set(Calendar.DATE, 4);
    calendar.set(Calendar.YEAR, 1776);
    Date time = calendar.getTime();
    System.out.println(time);
  }
}

这段代码中我们获得Calendar的实例,然后反复的调用它的方法。是否觉得冗余,因为我们的上下文环境是已知的,在Groovy中我们利用“with”来简化,上面的代码等价的Groovy代码如下:

// PrintIndependenceDay.groovy

def calendar = Calendar.instance
calendar.with {
  clear()
  set MONTH, JULY
  set DATE, 4
  set YEAR, 1776
  println time
}

是不是很简洁,我们还有更炫的功能,这要得益于delegate机制,看下面的例子:

// define a closure
def myClosure = {
  // call a method that does not exist
  append 'Jeff'
  append ' was here.'
}

// assign a delegate to the closure
def sb = new StringBuffer()
myClosure.delegate = sb

// execute the closure
myClosure()

assert 'Jeff was here.' == sb.toString()

通过动态机制,我们把闭包操作委托给了StringBuffer,我们要注意的是传递给闭包的只是StringBuffer的一个clone

同时我们还应该注意另外一点,首先看下面这个例子:

class ResolutionTest {  
      
    def append(arg) {  
        println "you called the append method and passed ${arg}"  
    }  
      
    def doIt() {  
        def myclosure = {  
            append 'Jeff was here.' 
        }  
          
        def buffer = new StringBuffer()  
          
        myclosure.delegate = buffer  
          
        // the append method in this ResolutionTest  
        // will be called because resolveStrategy is  
        // OWNER_FIRST (the default)  
        myclosure()

        println '---------------------------------'  

        // give the delegate first crack at method  
        // calls made inside the closure  
        myclosure.resolveStrategy = Closure.DELEGATE_FIRST  
          
        // the append method on buffer will  
        // be called because the delegate gets  
        // first crack at the call to append()  
        println myclosure()  
    }  
      
    static void main(String[] a) {  
        new ResolutionTest().doIt()  
    }  
}

输出结果:

you called the append method and passed Jeff was here.
---------------------------------
Jeff was here.

这里我们要注意闭包一个高级特性:闭包内部有一个策略来决定何时把调用发送给委托者,每一个Groovy的闭包有一个与之关联的属性:resolveStrategy。它有四个常量取值:OWNER_FIRST, DELEGATE_FIRST, OWNER_ONLY and DELEGATE_ONLY(都定义在groovy.lang.Closure中,默认取值为:OWNER_FIRST)

 

Groovy "with"的问题:

 

首先看一段测试代码:

class Foo {
    def add(x) {
        println "wrong add: $x"
    }
    def doit(x) {
        def n = [1,2,3]       
        n.with {
          add(x)
          each { println it }
        }

        n.add("after")     
        println n
    }
    def test() {
        doit("before")        
    }
}
new Foo().test()

打印结果为:

wrong add: before
Foo$_doit_closure1@1979eb
[1, 2, 3, "after"]

      从闭包的解析策略,我们看到,默认的策略为OWNER_FIRST,这样的话,相当于我们with中的所有调用都会委托给owner,这样的问题是,如果我们将来在闭包外增加了一个同名的方法,那么with中的调用将不会按照预期进行,好的解决方法是在with中手动指定策略为DELEGATE_ONLY。

      从上面的分析我们不难看懂最后的这个例子,因为each操作是Objec的方法,他其实调用的是Object的方法,这样我们的with中就不能调用所有Object的方法!

分享到:
评论

相关推荐

    Groovy in action

    Readers are presented with rich and detailed examples illustrating Groovy's enhancements to Java, including, # How to Work with Builders and the GDK, # Database programming with Groovy, Groovy in ...

    groovy_in_action_draft_ch_01.pdf

    Groovy is designed to integrate seamlessly with Java. It leverages the Java ecosystem, meaning that Java developers can easily transition to using Groovy without having to abandon their existing Java ...

    Apress.Introducing.Spring.Framework.A.Primer.

    This book is an introduction to the well-known Spring Framework that offers an inversion of control container for ...• Use Groovy with Spring. • Use the new Spring Boot and Spring XD technologies.

    [Groovy] Making Java Groovy 英文版

    Making Java Groovy is a practical handbook for developers who want to blend Groovy into their day to day work with Java It starts by introducing the key differences between Java and Groovy and how you...

    groovy-2.0.8-with-eclipse-plugin-2.7.2.part3

    groovy-2.0.8-with-eclipse-plugin-2.7.2.part3

    groovy包及相关学习资料

    - **GDK(Groovy Development Kit)**:Groovy扩展了Java的标准库,提供了许多方便的方法和类,如`each`、`with`等,简化了日常编程工作。 - **Meta-programming(元编程)**:Groovy支持元编程,允许在运行时修改...

    Groovy插件

    Groovy是一种动态、灵活的编程语言,它与Java有着紧密的联系,可以在Java平台上无缝运行。Eclipse是一款广泛使用的开源集成开发环境(IDE),对于Java开发者来说尤其受欢迎。为了在Eclipse中使用Groovy进行开发,你...

    Groovy User Guide

    7. **设计模式 (Design Patterns with Groovy)** - **内容:** 探讨了如何使用 Groovy 实现常见的设计模式,如工厂模式、适配器模式、单例模式等。 - **适用场景:** 在开发过程中解决特定的设计问题。 8. **动态...

    Groovy and Grails Recipes(清晰PDF)

    Getting Started with Groovy** - **介绍**: 本章主要介绍了如何开始使用Groovy编程语言。对于初次接触Groovy的新手来说,这是一个很好的起点。 - **核心知识点**: - 安装Groovy环境 - Groovy脚本的基本语法 - ...

    Agile Development with Groovy and Grails.pdf

    在《Agile Development with Groovy and Grails》这本著作中,作者Christopher M. Judd(Judd Solutions, LLC 的总裁兼顾问)详细介绍了如何运用Groovy和Grails框架进行敏捷软件开发。此书不仅适合那些对敏捷方法论...

    groovy-1.5.6-installer

    of Groovy: “Groovy is an agile dynamic language for the Java Platform with many features that are inspired by languages like Python, Ruby and Smalltalk, making them available to Java developers using...

    Groovy 2.3.6 windows

    首先,Groovy 2.3系列带来了对Java 7的全面支持,这允许开发者利用Java的新特性,如try-with-resources语句和多线程fork/join框架。同时,它也保持了与Java 6的兼容性,使得在旧环境下仍能顺畅运行。 Groovy的动态...

    Groovy 学习笔记

    2. **Ant with Groovy**: Groovy可以作为Ant任务的语言,使Ant脚本更加简洁和强大。 **五、Groovy的其他应用** 1. **脚本编写**: Groovy的简洁语法使其成为编写自动化脚本的理想选择,如系统管理、测试和持续集成...

    GROOVY入门经典

    他们的另一部著作《Object-Oriented Design with UML and Java》也深受业界好评。本书的特点是内容全面详尽,浅显易懂,并且易于选择性阅读,非常适合自学者。书中的内容不仅涵盖了Groovy语言的基础知识,还深入介绍...

    apache groovy 2.4.8

    3. **GDK (Groovy Development Kit)**:Groovy扩展了Java标准库,提供了一系列方便的方法,如`with`、`each`、`collect`等,这些都极大地提升了代码的可读性和效率。 4. ** Grape**: Groovy的依赖管理工具Grape允许...

Global site tag (gtag.js) - Google Analytics