반응형
<출처 : http://javaora.tistory.com/entry/Learning-the-JavaFX-Script-Programming-Language-Lesson-7-Expressions >

목차
- 블록구문(Block Expression)
- if문(The if Expression)
- Range구문(Range Expression)
- for문(The for Expression)
- while문(The while Expression)
- break & continue구문(The break and continue Expression)
- 예외처리구문(The throw, try, catch and finally Expression)


* 블록구문

블록구문은 중괄호로 둘러싸인 선언문과 구문들의 집합이다. 블록구문의 값은 가장 마지막 구문의 값이다. 만일 블록구문에 어떠한 (var나 def 같은) 구문도 포함되어 있지 않다면, 그 블록구문은 Void 타입니다. 

var nums = [5, 7, 3, 9];
var total = {
var sum = 0; 
for (a in nums) { 
sum += a // num의 값을 모두 더한다.
}; 
sum; // 합계인 sum을 리턴한다.
println("Total is {total}.");

Total is 24.

위 예제에서 total 다음에 나오는 중괄호 부분이 블럭구문이다.


* if문

if문은 그동안 자바나 다른 언어를 통해 한번쯤 보았을 익숙한 구문이다. if 다음에 조건식을 입력하고 이것이 참일때 아래 구문이 실행된다. 첫번째 조건이 참이 아닐 경우 다른조건을 줄때는 else-if 를, 조건이외의 경우에는 else 를 사용하는 방식 또한 동일하다.

def age = 8;
var ticketPrice;
if (age < 5 ) {
     ticketPrice = 0; // age가 5보다 작을 경우
} else if (age < 12 or age > 65) {
     ticketPrice = 5;  // age가 12보다 작거나 65보다 큰 경우
} else {
     ticketPrice = 10;  // 위 조건을 제외한 모든 경우
}
println("Age: {age} Ticket Price: {ticketPrice} dollars.");

Age: 8 Ticket Price: 5 dollars.

위 코드는 아래와 같이 간결한 조건의 표현으로 정리 될 수 있다.

ticketPrice = if (age < 5) 0 else if (age > 5 and age < 12) 5 else 10;


* Range문

시퀀스 레슨에서 연이어지는 숫자의 시퀀스는 짧은 방식으로 표기하는 것을 배웠었다.

var num = [0..5];

기술적으로 말하자면, 위 [0..5] 와 같은 방식을 Range문 이라 한다. 위 코드에선 숫자사이의 간격(interval)은 1 이다, 하지만 step 이라는 키워드를 사용하여 이를 다른 간격만큼 증가하도록 조절 할 수 있다. 가령 1 에서 10 사이의 홀수(odd number)인 시퀀스를 만드는 방법은 아래와 같다.

var nums = [1..10 step 2];
println(nums);

출력한 결과는 다음과 같다.

[ 1, 3, 5, 7, 9 ]

감소하는 range 문을 만들기 위해선 첫번째 값이 두번째 값보다 커야 하며 step 키워드 다음에 나오는 간격(interval)은 음수(negative)여야 한다.

var nums = [10..1 step -1];
println(nums);

결과는 다음과 같다.

[ 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 ]

만일 감소하는 방식의 range문을 사용하면서 간격값으로 음수를 사용하지 않으면 컴파일시 다음과 같은 에러가 발생한다.

D:\workspace>javafxc range.fx
range.fx:1: warning: empty sequence range literal, probably not what you meant.
var nums = [10..1 step 1];
^
1 warning

D:\workspace>javafx range
[ ]

만일 step 키워드 와 증감값(interval)을 정확히 사용하지 않는다면 위와 같이 빈 시퀀스(empty sequence)를 받게 될것이다.


* for문

또 다른 시퀀스와 관련된 표현으로는 for문이 있다. for문은 시퀀스 아이템을 통한 루프 기능을 제공한다.

var days = ["Mon","Tue","Wed","Thu","Fri","Sat","Sun"];

for (day in days) {
     println(day);
}

결과는 다음과 같다.

Mon
Tue
Wed
Thu
Fri
Sat
Sun

위 코드에서 보듯이 for문은 for로 시작하며, 조건의 내용을 살펴보면 days는 시퀀스의 이름을 day 는 시퀀스 만큼 돌아가는 루프에서 현재 아이텀을 의미한다.

여기서 day 변수는 따로이 선언할 필요는 없으며, 그 범위는 해당 루프로 한정된다.

위 예에서 for문은 별도의 리턴 값이 없었지만, for문은 시퀀스를 리턴시킬 수 있다. 아래의 두가지 예를 보면 하나의 시퀀스를 통해 또 다른 시퀀스를 만들어 내는 것을 볼 수 있다.

// 결과 시퀀스는 본래 시퀀스 값의 제곱값들로 이루어진 시퀀스를 리턴받는다.
var squares = for (i in [1..10]) i*i;

// 결과 시퀀스는 ["MON", "TUE", "WED", and so on...] 와 같이 대문자로 이루어진다.
var capitalDays = for (day in days) day.toUpperCase();

위 예제에서 사용된 toUpperCase() 는  String 객체의 함수로 API 문서를 통해 확인 해볼 수 있다.


* while문

또 다른 루프문으로는 while문이 있다. while문은 for와는 달리 시퀀스의 아이템들로 작동하지 않으며, 주어진 조건이 false 일때 까지 루프를 돈다. while문의 리턴 타입은 Void 이다.


var count = 0;
while (count < 10) {
    println("count == {count}");
    count++;
}

결과는 아래와 같다.

count == 0
count == 1
count == 2
count == 3
count == 4
count == 5
count == 6
count == 7
count == 8
count == 9

위 예제 코드를 보면 변수 count 를 선언하고 값으로 0을 넣은 후 조건이 만족하지 않을 때까지 루프가 돌게 된다. 해당 조건은 count가 10보다 작은 동안이며, 값이 true인 경우 count의 값을 프린트하고  count 값을 1 증가 시킨다. 그리고 다시 조건을 확인하고 그 값이 false 일 때까지 반복한다.


* break 와 continue구문

break 와 continue구문은 루프문들과 관련이 있다. 이 두 구문들은 루프의 반복작업에 영향을 미친다. break 는 전체 루프를 종료시키고, 그에 반해 continue 는 이번 루프만(이번 반복작업만) 건너 뛰고 진행된다. break 와 continue 의 리턴 타입은 Void 이다.

for (i in [0..10]) {
     if (i > 5) { // i 가 5보다 크면 for문 전체를 종료한다.
          break;
     }

     if (i mod 2 == 0) { // i 가 짝수이면 건너 뛴다.
          continue;
     }

     println(i); // 위 continue문을 통해 결과적으로 5이하의 홀수만 프린트 한다.
}

결과는 아래와 같다.

if (i mod 2 == 0) {
continue;
}



* 예외처리구문(The throw, try, catch and finally Expression)

프로그램 구동 중에 어떤 문제가 발생하는 경우 우리는 이를 Exception이라 한다.(일반적인 의미의 Error라 보면 된다.) 가령 프로그램상에서 특정 파일을 찾아 읽는 코드가 있는데 해당 path에 해당 파일이 존재하지 않는 경우 Exception이 발생된다.

아래 예는 함수에서 Exception을 던지는 것을 정의하는 모습니다.

import java.lang.Exception;

foo();

println("The script is now executing as expected... ");

function foo() {
     var somethingWeird = false;

     if(somethingWeird){
          throw new Exception("Something weird just happened!");
     } else {
          println("We made it through the function.");
     }
}

위 스크립트를 실행하면 아래와 같은 결과가 나온다.

We made it through the function.
The script is now executing as expected...


하지만 somethingWeird 값이 true 로 바뀐다면 다음과 같은 Exception이 발생할 것이며, 충돌로 프로그램에 악영향을 끼친다.

Exception in thread "main" java.lang.Exception: Something weird just happened!
at exceptions.foo(exceptions.fx:10)
at exceptions.javafx$run$(exceptions.fx:3)


이와 같은 충돌을 방지하여면 foo() 함수가 호출되는 부분에 try/catch 구문으로 감싸주는 것이 필요하다.

try {
     foo();
} catch (e: Exception) {
     println("{e.getMessage()} (but we caught it)");
}

이렇게 try/catch문을 사용하면 해당 함수 호출시 Exception이 발생하면 catch 부분에서 이를 잡아내서 그 내부 구문을 실행한다. 이제 프로그램을 다시 실행하면 아래와 같은 결과가 나온다.

Something weird just happened! (but we caught it)
The script is now executing as expected...


finally 구문은 try/catch 다음에 꼭 실행되는 부분으로 이부분을 통해 자원해제등을 수행하거나 그외 필요한 마무리 작업을 기술한다.

try {
     foo();
} catch (e: Exception) {
     println("{e.getMessage()} (but we caught it)");
} finally {
     println("We are now in the finally expression...");
}

결과는 다음과 같다.

Something weird just happened! (but we caught it)
We are now in the finally expression...
The script is now executing as expected...

+ Recent posts