【问题标题】:binding and closures groovy绑定和闭包 groovy
【发布时间】:2011-03-15 06:46:13
【问题描述】:

我不知道如何在 Groovy 中使用闭包绑定。我写了一个测试代码,在运行它时,它说,在作为参数传递的闭包上缺少方法setBinding

void testMeasurement() {
    prepareData(someClosure)
}
def someClosure = {
  assertEquals("apple", a)
}


  void prepareData(testCase) {
    def binding = new Binding()
    binding.setVariable("a", "apple")
    testCase.setBinding(binding)
    testCase.call()

  }

【问题讨论】:

    标签: binding groovy closures


    【解决方案1】:

    这适用于 Groovy 1.7.3:

    someClosure = {
      assert "apple" == a
    }
    void testMeasurement() {
      prepareData(someClosure)
    }
    void prepareData(testCase) {
      def binding = new Binding()
      binding.setVariable("a", "apple")
      testCase.setBinding(binding)
      testCase.call()
    }
    testMeasurement()
    

    在这个脚本示例中,setBinding 调用在脚本绑定中设置a(如您所见from the Closure documentation,没有setBinding 调用)。所以在setBinding调用之后,就可以调用

    println a
    

    它会打印出“苹果”

    因此,要在类中执行此操作,您可以为闭包设置委托(当本地无法找到属性时,闭包将恢复为该委托),如下所示:

    class TestClass {
      void testMeasurement() {
        prepareData(someClosure)
      }
    
      def someClosure = { ->
        assert "apple" == a
      }
    
      void prepareData( testCase ) {
        def binding = new Binding()
        binding.setVariable("a", "apple")
        testCase.delegate = binding
        testCase.call()
      }
    }
    

    它应该从委托类中获取来自a 的值(在本例中为绑定)

    This page here 遍历闭包中委托的用法和变量的作用域

    确实,您应该可以使用简单的 Map 而不是使用 Binding 对象,如下所示:

      void prepareData( testCase ) {
        testCase.delegate = [ a:'apple' ]
        testCase.call()
      }
    

    希望对你有帮助!

    【讨论】:

      【解决方案2】:

      这真是奇怪的行为:删除 someClosure 声明前面的“def”使脚本在 JDK1.6 Groovy:1.7.3 中工作

      更新:这已发布在上面的答案中。我的错误是重复它。 更新:为什么有效?没有 def 的第一行被视为调用 setProperty 并使变量在绑定中可用的属性分配,稍后解决。 一个 def 应该 和 (http://docs.codehaus.org/display/GROOVY/Groovy+Beans) 一样有效

      someClosure = {
          assert "apple", a
          print "Done"
      }
      
      void testMeasurement() {
          prepareData(someClosure)
      }
      
      void prepareData(testCase) {
          def binding = new Binding()
          binding.setVariable("a", "apple")
          testCase.setBinding(binding)
          testCase.call()
      }
      testMeasurement()
      

      我可以通过以下代码重现您提到的问题。但我不确定这是否是使用绑定的正确方法。 GroovyDocs 说它们将与脚本一起使用。你能否指出我建议使用闭包绑定的文档。

      class TestBinding extends GroovyTestCase {
          void testMeasurement() {
              prepareData(someClosure)
          }
      
          def someClosure = {
              assertEquals("apple", a)
          }
      
          void prepareData(testCase) {
              def binding = new Binding()
              binding.setVariable("a", "apple")
              //this.setBinding(binding)
              testCase.setBinding(binding)
              testCase.call()
          }
      }
      

      这已在 groovy 邮件列表中得到回答:

      在脚本中,def foo 将创建一个局部变量,而不是一个属性 (私有字段 + getter/setter)。 把脚本想象成一个 run() 或 main() 方法的主体。 这就是定义局部变量的位置和方式。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-12-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-08-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多