Lua 함수
Lua뿐만 아니라 많은 프로그래밍 언어에서 빼놓을 수 없는 개념 중 하나로 함수가 있다. 사실 지금까지 함수를 여러 번 사용하였다. 예를 들어 print
도 함수이고, io.read
도 함수이다. 함수는 여러 명령어를 모아 하나의 덩어리로 정의한 것이다. 같은 처리를 여러 번 하고 싶을 때는 함수를 하나 정의하고 호출하면 된다.
함수 만들기
이제 함수를 만들어 보자. 함수는 다음과 같이 정의한다.
형식
function 함수명(인수)
처리
end
이제 두 개의 값을 인수로 전달받아 그 합을 구하는 함수를 만들어 보자.
function sum(x, y)
return x + y
end
hoge = 10
piyo = 20
result = sum(hoge, piyo)
print(hoge .. " + " .. piyo .. " = " .. result)
실행 결과:
10 + 20 = 30
먼저 sum
함수를 사용하기 전에 함수를 정의해야 한다는 점에 유의하자. 함수에 원하는 이름을 붙이면 된다. 단, 이미 사용 중인 함수나 변수 이름은 사용하지 말아야 한다. 예를 들어, print
와 같은 이름을 붙이지 않는다. 함수 이름 지정 규칙은 변수와 동일하다.
C 언어와의 차이점
- 프로토타입 선언이 없다
이제 함수를 호출할 때, 아래와 같이 하였다.
sum(hoge, piyo)
함수를 호출할 때 인수라는 것을 전달한다. 이 인수는 어떤 것일까?
위 그림은 인수의 모습을 나타낸 그림이다. 호출한 쪽의 인수를 인자(argument, 실제 인수)라고 하고, 호출받은 쪽의 인수를 매개변수(parameter, 임시 인수)라고 한다.
이 때, 인자의 값이 매개변수의 값으로 복사된다.
function func(x, y)
x = 10
y = 20
end
hoge = 12
piyo = 22
func(hoge, piyo)
print(hoge, piyo)
즉 위와 같이 호출하더라도 x
,y
는 hoge
, piyo
의 복사본이므로 내용을 아무리 다시 작성해도 호출 원본인 hoge
, piyo
에는 영향을 미치지 않는다.
인수와 관련하여, 어쩌면 아무것도 받을 필요가 없는 경우가 있을 수 있다. 이 경우, 인수를 비워두면 된다.
함수의 반환값에 대해서는 다음 장에서 설명한다.
함수의 반환값
함수에는 반환값이라는 것이 존재한다. 앞에서 설명한 프로그램과 아래 그림을 참고해보자.
return
은 함수를 호출한 측에 값을 반환하는 명령어이다. 여기서 x + y
의 계산 결과를 호출자에게 반환한다. 즉, 변수 result
에는 계산 결과가 대입된다.
Lua는 여러 개의 값을 반환할 수 있다. 예를 들어, 다음과 같이 할 수 있다.
function func()
return 10, 20
end
hoge, piyo = func()
print(hoge, piyo)
실행 결과:
10 20
hoge
에는 10이, piyo
에는 20이 대입된다.
그렇다면 다음과 같은 코드를 작성하면 어떻게 될까?
function func()
return 10, 20
end
hoge = func()
print(hoge, piyo)
이 경우 두 번째 반환값인 20은 사용되지 않고 사라진다.
실행 결과:
10 nil
또한, 다음과 같은 코드를 작성했다면 어떨까?
function func()
return 10
end
piyo = 20
hoge, piyo = func()
print(hoge, piyo)
두 번째 반환값은 없다. 이 경우 piyo
에는 nil
이 할당된다. piyo
는 20이 아니므로 주의해야 한다.
실행 결과:
10 nil
아무것도 반환하지 않는 함수
반환값 함수, 즉 아무것도 반환하지 않는 함수를 만들 수도 있다. 이 경우 return
을 작성하지 않아도 된다.
function func()
print("함수가 호출되었다")
end
func()
실행 결과:
함수가 호출되었다.
또한, 명시적으로 반환값이 없음을 나타내기 위해 return
만 작성할 수도 있다.
function func()
print("함수가 호출되었다")
return
end
func()
위의 두 코드는 완전히 동일한 코드이다.
변수에 함수 대입하기
Lua의 변수에는 어떤 값이라도 대입할 수 있다. 심지어 함수라도 대입이 가능하다. 예를 들어 다음과 같은 것도 가능하다.
function sum(x, y)
return x + y
end
function mul(x, y)
return x * y
end
hoge = sum
print("hoge is " .. type(hoge));
print("10 + 20 is " .. hoge(10, 20))
hoge = mul
print("10 * 20 is " .. hoge(10, 20))
type
함수는 현재 변수의 타입을 검사하는 함수이다. hoge
에는 sum
함수와 mul
함수를 대입하고 있다. 그리고 hoge
를 사용하여 함수에 접근할 수도 있다. C언어를 아는 사람은 함수 포인터와 같은 역할을 할 수 있다고 생각하면 된다.
실행 결과:
hoge is function
10 + 20 is 30
10 * 20 is 200
함수 안에서 함수 정의하기
Lua에서는 함수 내에서 함수를 정의할 수도 있다.
function func(x)
local function get()
return x
end
local function add(value)
x = x + value
end
return get, add
end
firstGetValue, firstAddValue = func(10)
secondGetValue, secondAddValue = func(30)
print("first value : " .. firstGetValue())
print("second value : " .. secondGetValue())
firstAddValue( 15 )
secondAddValue( 20 )
print("first value : " .. firstGetValue())
print("second value : " .. secondGetValue())
func
함수는 get
과 add
함수를 반환값으로 반환한다. 여기서 local
이라는 새로운 키워드가 등장했다. 이 local
에 대해서는 유효범위 장에서 자세히 설명한다. 간단히 설명하면, local
이라는 키워드를 붙이면 로컬 변수(또는 로컬 함수)를 생성할 수 있다. 즉, get
함수도 add
함수도 func
함수 내에서만 호출할 수 있다는 뜻이다.
실행 결과:
first value : 10
second value : 30
first value : 25
second value : 50
무명 함수
이름 없는 함수를 만들 수도 있다. 예를 들어, 다음과 같은 코드를 작성할 수 있다.
function createSquare()
return function(x)
return x * x
end
end
square = createSquare()
print("10 * 10 is " .. square(10, 10))
createSquare
함수는 반환값에 x * x
를 하는 함수를 반환한다.
실행 결과:
10 * 10 is 100
기본 라이브러리
여기서는 기본 라이브러리에 제공되는 함수 중 일부를 소개한다.
assert 함수
정의
assert (v [, message])
assert
함수는 v
가 거짓 조건일 경우 에러를 발생시키는 함수이다.
message
에는 에러 메시지를 전달한다. 에러 메시지는 생략할 수 있다.
hoge = true
assert(hoge, "Error #1")
hoge = false
assert(hoge, "Error #2")
실행 결과:
lua: test.lua:4: Error #2
stack traceback:
[C]: in function 'assert'
test.lua:4: in main chunk
[C]: in ?
dofile 함수
정의
dofile(filename)
dofile
함수는 filename
으로 지정한 파일을 실행하는 함수이다. 예를 들어 다음과 같이 사용한다. 이번에는 두 개의 Lua 파일인 test.lua
와 call.lua
에 코드를 작성하였다.
call.lua
function testFunc()
print ("Hello")
return "World!"
end
test.lua
dofile("call.lua")
hoge = testFunc()
print(hoge)
실행 결과:
Hello
World!
dofile
에서 call.lua
를 불러오면 test.lua
측에서 testFunc
함수를 사용할 수 있다.
type 함수
정의
type(v)
type
함수는 데이터의 타입을 반환하는 함수이다.
hoge = nil
print("hoge : " .. type(hoge))
hoge = 10
print("hoge : " .. type(hoge))
hoge = true
print("hoge : " .. type(hoge))
hoge = "Hello"
print("hoge : " .. type(hoge))
실행 결과:
hoge : nil
hoge : number
hoge : boolean
hoge : string
tonumber 함수
정의
tonumber (e [, base])
tonumber
함수는 인수 e
를 숫자로 변환하는 함수이다. 숫자 변환이 가능하면 숫자를 반환하고, 그렇지 않으면 nil
을 반환한다.
또한, base
를 지정하면 e를 base 진법의 숫자로 변환한다. 생략하면 10이 자동으로 지정된다.
hoge = "25"
print("hoge :" .. hoge .. " type :" .. type(hoge))
piyo = tonumber(hoge)
print("piyo :" .. piyo .. " type :" .. type(piyo))
실행 결과:
hoge :25 type :string
piyo :25 type :number
tostring 함수
정의
tostring(e)
tostring
함수는 e
를 문자열로 변환하는 함수이다.
hoge = 25
print("hoge :" .. hoge .. " type :" .. type(hoge))
piyo = tostring(hoge)
print("piyo :" .. piyo .. " type :" .. type(piyo))
실행 결과:
hoge :25 type :number
piyo :25 type :string
숫자를 문자열로 변환할 때는 tostring
함수를 사용하지 않고 빈 문자열을 추가해도 된다.
piyo = hoge .. ""