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와 같은 이름을 붙이지 않는다. 함수 이름 지정 규칙은 변수와 동일하다.

이제 함수를 호출할 때, 아래와 같이 하였다.

sum(hoge, piyo)

함수를 호출할 때 인수라는 것을 전달한다. 이 인수는 어떤 것일까?

Lua Function

위 그림은 인수의 모습을 나타낸 그림이다. 호출한 쪽의 인수를 인자(argument, 실제 인수)라고 하고, 호출받은 쪽의 인수를 매개변수(parameter, 임시 인수)라고 한다.

이 때, 인자의 값이 매개변수의 값으로 복사된다.

function func(x, y)
    x = 10
    y = 20
end

hoge = 12
piyo = 22
func(hoge, piyo)

print(hoge, piyo)

즉 위와 같이 호출하더라도 x,yhoge, piyo의 복사본이므로 내용을 아무리 다시 작성해도 호출 원본인 hoge, piyo에는 영향을 미치지 않는다.

인수와 관련하여, 어쩌면 아무것도 받을 필요가 없는 경우가 있을 수 있다. 이 경우, 인수를 비워두면 된다.

함수의 반환값에 대해서는 다음 장에서 설명한다.

함수의 반환값

함수에는 반환값이라는 것이 존재한다. 앞에서 설명한 프로그램과 아래 그림을 참고해보자.

Lua Function

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 함수는 getadd 함수를 반환값으로 반환한다. 여기서 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.luacall.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 .. ""



최종 수정 : 2024-04-22