`
lixw
  • 浏览: 196991 次
  • 性别: 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.2nd.Edition.1935182

    With relevant examples, careful explanations of Groovy's key concepts and features, and insightful coverage of how to use Groovy in-production tasks, including building new applications, integration ...

    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 ...

    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

    Learning.Groovy.3.Java-Based.Dynamic.Scripting.2nd.Edition (英文版pdf)

    This book covers Groovy fundamentals, such as installing Groovy, using Groovy tools, and working with the Groovy Development Kit (GDK). You'll also learn more advanced aspects of Groovy, such as ...

    Agile Development with Groovy and Grails.pdf

    Agile Development with Groovy and Grails.pdf

    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 and Grails Recipes(清晰PDF)

    CHAPTER 1 Getting Started with Groovy CHAPTER 2 From Java to Groovy CHAPTER 3 Groovy Data Types and Control Structures CHAPTER 4 Object-Oriented Groovy CHAPTER 5 Closures CHAPTER 6 Builders ...

    groovy 1.6.9

    Groovy... * is an agile and dynamic language for the Java Virtual Machine * builds upon the strengths of Java but has additional power features inspired by languages like Python, Ruby and Smalltalk...

    Learning Groovy(Apress,2016)

    This book covers Groovy fundamentals, such as installing Groovy, using Groovy tools, and working with the Groovy Development Kit (GDK). You’ll also learn more advanced aspects of Groovy, such as ...

    Groovy in Action 2nd Edition-Manning(2016)

    space agencies watch the stars with the help of Groovy, and satellite live-data streams are handled by Groovy code. Groovy is traveling the oceans, shipping containers around the globe, helping ...

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

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

    Groovy in Action(Manning,2ed,2015)

    It introduces Java developers to the dynamic features that Groovy provides, and shows how to apply Groovy to a range of tasks including building new apps, integration with existing code, and DSL ...

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

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

    Making java groovy

    For interacting with XML payloads, web services, or databases, Groovy provides handy and elegant wrappers around the Java Development Kit that make those tasks a breeze. And for writing business rules...

    GWTGrailsTutorial 实面gwt和grails groovy集成

    A tutorial showing how do develop a Grails application with a GWT UI. Prepare your system The first step is to set up your system for running Grails and the GWT. You will also need to create a new ...

    Gradle Effective Implementations Guide, Second Edition--2016

    What You Will Learn Write your first Gradle Script Write build logic with the Gradle ... Integrate Scala and Groovy with Gradle Write your own custom tasks and plugins Integrate Gradle with your IDE

    The Groovy Programming Language

    The Groovy Programming Language Agenda • Background • What is Groovy? • Language Details • Working with Java • Groovy Markup • Extras • Conclusion

Global site tag (gtag.js) - Google Analytics