시작하기 전에...#

당신이 아래에서 볼 예제를 실행하기 전에, 당신은 먼저 Groovy를 다운로드 하고 설치 한 뒤, 이것을 수행하는 방법을 배워야 한다.

첫번재 Groovy#

//hello.groovy
println "hello, world"
for (arg in this.args ) {
  println "Argument:" + arg;
}
// this is a comment
/* this is a comment for block.you can do like this
this.args.each{ arg ->
 println "hello, ${arg}"
}
*/
이것을 명령창에서 실행하기 위해 다음처럼 수행해야 한다.

groovy hello.groovy MyName yourName HisName

개요#

Groovy클래스는 자바 바이트코드로 컴파일되어서 Groovy클래스와 자바 클래스간에 1대1 맵핑이 된다. 각각의 Groovy클래스는 자바코드내에서 사용될수 있다.

Groovy를 배우기 가장 쉬운 방법은 집합(collection)을 사용해보는 것이다. Groovy List(java.util.List)와 Map(java.util.Map) 모두 문법적으로 가장 첫 클래스 객체이다. 그래서 당신은 다음처럼 객체의 List를 생성한다.

def list = [12'hello', new java.util.Date()]
assert list.size() == 4
assert list.get(2== 'hello'
assert list[2== 'hello'

모든 것이 객체라는 사실을 기억하자. (그래서 숫자를 갖고 작업하면 오토박싱이 동작한다) 맵을 만들려면... Notice that everything is an object (or that auto-boxing takes place when working with numbers). To create maps...

def map = ['name':'James', 'location':'London']
assert map.size() == 2
assert map.get('name') == 'James'
assert map['name'] == 'James'

Iterating over collections is easy... 컬렉션을 iterate하는 것도 쉽다...

def list = [123]
for (i in list) { println i }

일단 컬렉션을 만들었으면, 새로운 컬렉션 헬퍼 메쏘드를 사용하거나 클로져로 작업을 해보자... Once you have some collections you can then use some of the new collection helper methods or try working with closures...

Working with closures#

임의의 파라미터로 사용할 수 있다는 점만 제외하면 클로져는 자바의 inner class와 비슷하다. 클로져에는 원하는 만큼 파라미터를 쓸 수 있다. Closures are similar to Java's inner classes, except they are a single method which is invokable, with arbitrary parameters. A closure can have as many parameters as you wish...

def closure = param -> println("hello ${param}") }
closure.call("world!")

closure = greeting, name -> println(greeting + name) }
closure.call("hello ""world!")

If no parameter(s) is(are) specified before -> symbol then a default named parameter, called 'it' can be used. e.g.

def closure = println "hello " + it }
closure.call("world!")

Using closures allows us to process collections (arrays, maps, strings, files, SQL connections and so forth) in a clean way. e.g

[123].each ({ item -> print "${item}-" })
["k1":"v1""k2":"v2"].each {key, value -> println key + "=" + value}

Note: If a given closure is the last parameter of a method, its definition can reside outside of the parentheses. Thus the following code is valid:

def fun(int i, Closure c) {
  c.call(i)
}

// put Closure out of ()
[123].each() ({ item -> print "${item}-" })
fun(123) { i -> println i }

// omit ()
[123].each ({ item -> print "${item}-" })

// normal
 [123].each(({ item -> print "${item}-" }))

def closure = i -> println i}

//[1, 2, 3].each() closure // error. closure has been defined

Here are a number of helper methods available on collections & strings...

each#

iterate via a closure

[123].each item -> print "${item}-" }

collect#

collect the return value of calling a closure on each item in a collection

def value = [123].collect it * }
assert value == [246]

find#

finds first item matching closure predicate

def value = [123].find it > }
assert value == 2

findAll#

finds all items matching closure predicate

def value = [123].findAll it > }
assert value == [23]
inject

allows you to pass a value into the first iteration and then pass the result of that iteration into the next iteration and so on. This is ideal for counting and other forms of processing

def value = [123].inject('counting: ') str, item -> str + item }
assert value == "counting: 123"

value = [123].inject(0) { count, item -> count + item }
assert value == 6

In addition there's 2 new methods for doing boolean logic on some collection...

every#

returns true if all items match the closure predicate

def value = [123].every it < }
assert value

value = [123].every item -> item < }
assert ! value

any#

returns true if any item match the closure predicate

def value = [123].any it > }
assert value

value = [123].any item -> item > }
assert value == false

Other helper methods include:

max / min#

returns the max/min values of the collection - for Comparable objects

value = [942105].max()
assert value == 10
value = [942105].min()
assert value == 2
value = ['x''y''a''z'].min()
assert value == 'a'

join#

concatenates the values of the collection together with a string value

def value = [123].join('-')
assert value == '1-2-3'

Also the 'yield' style of creating iterators, available in Python and Ruby via the yield statement, is available. The only difference is rather than using a yield statement, we're just using closures.

class Foo {
  myGenerator(Closure yield) {
    yield.call("A")
    yield.call("B")
    yield.call("C")
  }

  static void main(args) {
    def foo = new Foo()
    for (x in foo.myGenerator) {
        println x
    }
  }
}

def foo = new Foo()
for (x in foo.myGenerator) {
  print("${x}-")
}

outputs A-B-C-

The use of Closure in the method prototype is optional. If we have syntax sugar for invoking closures as if they are method calls, then the generator method could look even more like the python/ruby equivalent. Especially if parentheses are optional...

class Foo {
  myGenerator(yield) {
    yield "A"
    yield "B"
    yield("C")
  }

  static void main(args) {
    def foo = new Foo()
    foo.myGenerator println "Called with ${it}" }
  }
}

Add new attachment

Only authorized users are allowed to upload new attachments.
« This page (revision-3) was last changed on 08-Nov-2006 10:53 by 211.221.195.109