루아의 변수는 다음과 같이 8가지 데이터타입을 갖는다.


nil

부울값

숫자

문자열

테이블

함수

----------

코루틴

유저데이터


이 중에서 코루틴과 유저데이터는 코로나SDK와 별로 관련이 없으므로 제외하고 나머지 여섯 개 중 참조를 갖는 것은 함수와 테이블이다. 문자열은 참조가 아니라는 것에 유의해야 한다. 참조란 실제 데이터가 저장된 곳을 가리키는 주소이다. (사실 참조도 주소'값'이므로 루아는 다 값이라고 주장하기도 하지만 혼동의 여지가 있으므로 여기서는 참조와 값을 구분하도록 하겠다.)

따라서 만약 어떤 테이블을 함수의 입력파라메터로 넘길 때 참조가 넘어가므로 그것을 받아서 조작하면 원래의 테이블값도 바뀌게 된다.


┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓

    local function Func1(a, tA)

        a = 20

        tA.x = 20

    end


    local function Func2(tA)

        tA = {x=30}

    end


    local x, tX = 10 , {x=10}

    Func1(x, tX) -- x는 값이, tX는 참조가 넘어간다.

    print(x, tX.x) -- 10, 20 이 찍힌다.

    Func2(tX)

    print(tX.x) --20이 찍힌다.

┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛


위의 예에서 Func1()을 호출할 때 로컬 변수 x는 값이 넘어가고 테이블 tX는 참조가 넘어가므로 함수 호출 후 테이블의 필드만 값이 변경되었다. 반면에 Func2()내에서는 tA가 tX의 참조를 받기는 하지만 새로운 테이블의 참조로 초기화되었다. 따라서 이경우 tA는 넘어온 tX와는 전혀 별개의 것이 되어서 tX에는 아무런 영향을 끼치지 못한다. 그래서 맨 마지막 print()에서 20이 찍히는 것이다.


이와 마찬가지로 함수의 리턴값이 테이블이나 함수일 경우도 참조를 반환한다. 다음 예는 처음에는 조금 이해하기 힘들 수 있으나 한 번 살펴보도록 하겠다.


┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓

    local function Func1(xR)

        local x = xR or 0 -- 내부변수 x를 넘어온 값으로 초기화

        local y = 0

        local Func = function() print("x :"..x);end -- 여기서 x가 사용되었다.

        return y, Func -- y는 '값'을, Func는 '참조'를 반환

    end


    local y1, Func2 = Func1(10)

    local y2, Func3 = Func1(20)

    Func3() -- 20 이 찍힌다.

    Func2() -- 10 이 찍힌다.

┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛


함수 Func1()은 그 안에서 내부변수 y의 '값'과 내부변수 Func의 '참조'를 반환한다. 기본적으로 어떤 함수의 지역변수는 함수가 종료되면 사라진다는 것은 알고 있을 것이다. 변수 y는 함수가 종료되면 더 이상 참조되는 곳이 없으므로 GC의 타겟이 되어 사라질 것이다. 하지만 내부함수 Func는 그 참조가 호출된 곳의 Func2 변수를 통해서 계속 사용되므로 사라지지 않고 살아남게 된다. 그럼 내부변수 x는 어떨까? x변수는 Func안의 print()문에서 참조를 하고 있으므로 Func가 살아있는 한 x도 계속 살아있게 된다.


또 한가지 주의할 것은 Func2 와 Func3에서 참조하는 변수 x는 서로 별개의 것이라는 점이다. 따라서 처음 Func3()호출에는 20이 찍히고 맨 마지막 Func2() 함수를 호출하면 10이 찍힌다. 서로 '다른' 변수 x를 참조하고 있기 때문이다.


이것을 이해했다면 클래스를 구현할 때 외부에서는 접근할 수 없고 내부에서만 사용할 수 있는 private 변수/함수 를 구현하는데 응용할 수 있다.

Posted by 살레시오


  자바 식별자는 길이에 제한이 없으며 '_' 뿐만 아니라 '$' 문자도 사용할 수 있다는 점이 특이하다.


  자바에서는 반복문 앞에 라벨을 붙여서 그 라벨을 break, continue 문 뒤에 붙여 중첩된 반복문을 한꺼번에 벗어날 수 있다.


loop1: for(...) {

    for (… ) {

        …

        break loop1; //바깥쪽 루프를 벗어남.

        …

        continue loop1: //바깥쪽 루프의 그 다음 반복을 바로 수행.

    }

}


반복문의 이름이 지정되지 않은 break, continue 문은 그것을 포함하는 가장 안쪽의 반복문을 제어하지만 이처럼 라벨링을 이용하면 그 바깥쪽의 반복문을 제어할 수 있다.


  그리고 JAVA5 이상부터는 C#의 foreach 나 파이썬의 for문과 같은 기능을 사용할 수 있다. 문법은 다음과 같다.


for(자료형 변수명: 집합) {

}


여기서 집합은 배열,콜렉션,enum 등이다. 이렇게 하면 예를 들어 배열의 각 요소가 변수명에 대입되어 차례로 반복문을 수행하게 된다.

enum Week { 월, 화, 수, 목, 금, 토, 일 }

public static void main(String args []) {
    // enum 타입을 foreach 로 출력

    for (Week day : Week.values()) { // Week.values()에는 Week 의 값들이 교대로 들어갑니다.
    System.out.println(day + "요일");
}

// 정수 배열을 foreach 로 출력
int[] num = { 14, 54, 52, 26, 62, 55 };
for (int i : num)
    System.out.println(i);

// 문자열 배열을 foreach 로 출력
String names[] = { "수성", "금성", "지구", "화성" };
for (String s : names)
    System.out.println(s);
}


Posted by 살레시오

 심파이(sympy)에서 미리 정의된 상수들은 다음과 같은 것들이 있다.


[표 1] 심파이의 기정의된 상수들

sympy 상수
의미
I, 1j, 1J
허수. (예를 들어 3+4j 는 3+4*I 와 같이 입력해야 한다.)
pi
원주율(3.141592..)
E
자연상수(2.718281..)
nan
not a number
oo
(positive) infinity
zoo
complex infinity


허수로 I를 이용할 때는 허수부와 I 사이에 반드시 곱기호를 넣어 주어야 한다.


>>> abs(1+2*I)
sqrt(5)


무리수의 근사값을 알고 싶다면 evalf() 멤버함수를 이용하면 된다.


>>> pi.evalf()
3.14159265358979

>>> E.evalf()
2.71828182845905




Posted by 살레시오


티스토리 툴바