Groovy Closure с необязательными аргументами

Я хочу определить закрытие, которое принимает один аргумент (на который я ссылаюсь с помощью it ), иногда я хочу передать еще один дополнительный аргумент в закрытие. Как я могу это сделать?


person Moonlit    schedule 25.09.2012    source источник


Ответы (3)


Вы можете установить для второго аргумента значение по умолчанию (например, null):

def cl = { a, b=null ->
  if( b != null ) {
    print "Passed $b then "
  }
  println "Called with $a"
}

cl( 'Tim' )          // prints 'Called with Tim'
cl( 'Tim', 'Yates' ) // prints 'Passed Yates then Called with Tim

Другим вариантом было бы сделать b списком vararg следующим образом:

def cl = { a, ...b ->
  if( b ) {
    print "Passed $b then "
  }
  println "Called with $a"
}

cl( 'Tim' )                    // prints 'Called with Tim'
cl( 'Tim', 'Yates' )           // prints 'Passed [Yates] then Called with Tim
cl( 'Tim', 'Yates', 'Groovy' ) // prints 'Passed [Yates, Groovy] then Called with Tim
person tim_yates    schedule 25.09.2012
comment
@user1291235 user1291235 нет проблем :-) Добавлено еще одно возможное решение - person tim_yates; 25.09.2012
comment
И если вы не хотите менять тело замыкания, вы можете назвать первый аргумент it :-) - person Ayman; 25.09.2012
comment
по крайней мере, с 2.4.11 аргумент по умолчанию игнорируется и не компилируется с @TypeChecked :-( - с @TypeChecked(value=TypeCheckingMode.SKIP) он снова работает ... то же самое с версией varargs - person Andreas Covidiot; 05.04.2018

надеюсь, это поможет

​def clr = {...a ->  
    print "Passed $a then "
    enter code here

}

​clr('Sagar')
clr('Sagar','Rahul')
person Sagar Mal Shankhala    schedule 19.05.2016

Варианты из @tim_yates не работают с @TypeChecked (в контекст класса), по крайней мере, с Groovy 2.4.11, где аргумент по умолчанию игнорируется и не компилируется :-(

Таким образом, другие (по общему признанию, более уродливые) решения, которые будут работать в этом случае:

  1. сначала объявить о закрытии, кажется, работает нормально (в любом случае необходимо для рекурсии):

    def cl
    cl = { ... }
    
    • at least in Eclipse Neon / Groovy-Eclipse Plugin 2.9.2 the code completion/suggestions do not work either way using the closure later on in the same code block => so nothing lost as far as I can say
  2. с @TypeChecked(value=TypeCheckingMode.SKIP) это будет работать для обоих, но тогда вы потеряете проверку типов для метода (или класса, в зависимости от того, где вы его поместили)

  3. объявить делегат закрытия cl2:

    @TypeChecked
    class Foo { 
    
      static main( String[] args ) {
    
        def cl = { a, b ->
          if( b != null )
            print "Passed $b then "
          println "Called with $a"
        }
        def cl2 = { a -> cl( a, null ) }
    
        cl2( 'Tim' )         // prints 'Called with Tim'
        cl( 'Tim', 'Yates' ) // prints 'Passed Yates then Called with Tim           
      }
    }
    
  4. преобразовать замыкание в метод класса, например.

    @TypeChecked
    class Foo { 
    
      cl( a, b=null ) {
        if( b != null )
          print "Passed $b then "
        println "Called with $a"
      }
    
      static main( String[] args ) {
        cl( 'Tim' )          // prints 'Called with Tim'
        cl( 'Tim', 'Yates' ) // prints 'Passed Yates then Called with Tim           
      }
    }
    
person Andreas Covidiot    schedule 06.04.2018