Post List

2015년 5월 22일 금요일

Groovy에 대한 간단한 소개

Grails는 문법적으로 Groovy를 사용합니다.
Groovy에 대해서 체계적으로 공부를 하셔도 좋지만,
그럴만한 시간이 없으신 분들 중 빠르게 Grails 프로젝트를 진행해야 할 경우
최소한 이정도의 지식만 있어도 도움이 될 것입니다.


1. Java 와 Groovy의 문법적 차이

  - 세미콜론 ( ; ) 이 Optional (있어도 되고 없어도 됨) 입니다.

  - return 문이 Optional 입니다. return 문이 없을 경우 마지막에 실행된 결과가 return 됩니다.

  - 타입이 Optional 입니다. 추론 가능할 경우에는 def  로 선언이 가능합니다.

  - assert 문에서 == 는 .equal() 와 같은 역할을 합니다.

  - 함수 호출시 인자가 있는 경우는 괄호 ( ) 가 Optional 입니다.
    인자가 없는 경우는 괄호를 필수로 붙여줘야 합니다.

x = someMethodWithArgs arg1, arg2, arg3
y = someMethodWithoutArgs()

  - Groovy Class 생성시 getter( ), setter( )가 Optional 입니다.
    바로 해당 Property로 접근하면 자동으로 getter( )와 setter( )가 호출됩니다.

class Person {
    String name
}

def person = new Person()
person.name = 'LunaStar'
assert person.getName() == 'LunaStar'
person.setName('Luna')
assert person.name == 'Luna'

  생성하지 않아도 기본 getter( ), setter( ) 가 제대로 동작합니다.
  물론 따로 만들어주는 것도 가능합니다.

class Person {
    String name
    void setName(String val) {
        name = val.toUpperCase()
    }
}

def person = new Person(name:'Luna')
assert person.name == 'Luna'

  - named-args 생성자를 자동으로 만들어 줍니다.
    아래 예제 Code를 보면 이해가 빠를 거에요.

class Person {
    String name
    void setName(String val) {
        name = val.toUpperCase().reverse()
    }
}

Person p = new Person(name:'Luna')
assert p.name == 'ANUL'

    생성자에 Property 명과 값을 넣어서 생성이 가능합니다.


2. Groovy String (GString)

  GString : 쌍따옴표 ( " " ) 로 문자열을 정의합니다.
              문자열 사이에 $를 이용하여 value 삽입이 가능합니다.

def name = 'Luna'
def x = 3
def y = 7
def groovyString = "Hello ${name}, did you know that $x x $y equals ${x*y}?"
assert groovyString == 'Hello Luna, did you know that 3 x 7 equals 21?'

 Java String : 단따옴표 ( ' ' ) 로 문자열을 정의합니다.

3. Groovy Closures

  Java, C#의 lambda 식이라고 생각을 하시면 됩니다.

def c = {a, b -> a + b}

def name = 'Luna'
def c = {println "$name called this closure ${it+1} time${it > 0 ? 's' : ''}"}
assert c instanceof Closure
5.times(c)
Luna called this closure 1 time
Luna called this closure 2 times
Luna called this closure 3 times
Luna called this closure 4 times
Luna called this closure 5 times

4. Groovy Collection

* List 

 - [ x , x , x , ] 로 선언 가능

def colors = [' Red', 'Green', 'Blue', 'Yellow' ]
def empty = []
assert colors instanceof List
assert empty instanceof List
assert empty.class.name == 'java.util.ArrayList'

  - .each( ) : for-each 역할, it 가 각각의 single object

def names = ['Nate', 'Matthew', 'Craig', 'Amanda']

names.each{
    println "The name $it contains ${it.size()} characters."
}
The name Nate contains 4 characters.
The name Matthew contains 7 characters.
The name Craig contains 5 characters.
The name Amanda contains 6 characters.

  - .min( ) , .max( ) : 최소, 최대 원소 추출

assert names.min() == 'Amanda'
assert names.max() == 'Nate'

  - .sort( ) : closure 를 가질 수도 있는데, 인자가 없으면 it를 사용해서 표현

def sortedNames = names.sort()
assert sortedNames == ['Amanda','Craig','Matthew','Nate']
sortedNames = names.sort{ it.size() }
assert sortedNames == ['Nate','Craig','Amanda','Matthew']
sortedNames = names.sort{ obj1, obj2 -> obj1[2] <=> obj2[2] }
assert sortedNames == ['Craig','Amanda','Nate','Matthew']
  - <=> : compareTo( )

  - << : add( )

names << 'Jim'
assert names.contains('Jim')

* Map  

 - [ x:y, x:y ] 로 선언 가능
 - key : value 의 pair로 이루어진 collection

def family = [boys:7, girls:6, Debbie:1, Dave:1]
def empty = [:]

assert family instanceof Map
assert empty instanceof Map
assert empty.getClass().name == 'java.util.LinkedHashMap'

 - .each( ) : it 가 각각의 인자들이며, key 와 value를 가지고 있다.
              closure로 표현할 경우 : 첫번째 인자는 key, 두번째 인자는 value 이다.

def favoriteColors = [Ben:'Green',Solomon:'Blue',Joanna:'Red']
favoriteColors.each{ key, value -> println "${key}'s favorite color is ${value}." }
Ben's favorite color is Green.
Solomon's favorite color is Blue.
Joanna's favorite color is Red.

 - .key = value 방식을 이용하여 기존값의 get, set 및 새로운 값의 add 가 가능하다.

assert favoriteColors.Joanna == 'Red'
favoriteColors.Rebekah = 'Pink'
assert favoriteColors.size() == 4
assert favoriteColors.containsKey('Rebekah')

* Set 

 - [ x , x ] as Set 으로 선언
 - 중복값을 가질수 없으며, 인덱스 연산자 [ ] 의 사용이 안된다.
 - .toList( ) 를 이용하면 List로 변환이 가능하다.
 - << 로 add( ) 가 가능하다.

def employees = ['Susannah','Noah','Samuel','Gideon'] as Set
Set empty = []

assert employees instanceof Set
assert empty instanceof Set

assert empty.class.name == 'java.util.HashSet'

employees << 'Joshua'

assert employees.contains('Joshua')

println employees.toList()[4]